﻿Imports Commander_Wars.Spieletools
Public Class KIMittel
    Inherits ObjektKI
    ''' <summary>
    ''' Wenn wir feststellen, dass wir beispielsweise mit Eagle nochmal ziehen können, oder sowieso bei jeder Doppelgabe, dann sollte der Boolean auf True gesetzt werden. Dann ignoriert die KI es, dass sie noch angegriffen werden kann. Beim letzten mal alle Ziehen, muss der Boolean dann natürlich wieder zurückgesetzt werden!
    ''' </summary>
    ''' <remarks></remarks>
    Dim GegenschadenIgnorieren As Boolean = False
    ' Const cPräventivLebensabzug As Single = 0.2 '20% des Schadens erleiden die Einheiten tatsächlich
    Const MinimaleFonds As Integer = 10000
    Dim NächsteRundeGeld As Integer = 12000
    Const MinimalesEinkommen As Integer = 8000
    Const KartenGrößeFürInfiTransport = 100
    ''' <summary>
    ''' Wie weit die näheste Luftwaffe weg sein muss damit sich eine Missile lohnt!
    ''' </summary>
    ''' <remarks></remarks>
    Const LuftwaffenAbstand As Integer = 10
    ''' <summary>
    ''' Infi Flut Muaha!
    ''' </summary>
    ''' <remarks></remarks>
    Const MinimalEinkommen = 4000
    ''' <summary>
    ''' Infi-Flut
    ''' </summary>
    ''' <remarks></remarks>
    Const MinimaleKartenGröße As Integer = 400
    ''' <summary>
    ''' Ein Panzer muss teurer sein als...
    ''' </summary>
    ''' <remarks></remarks>
    Const MinimalerPanzerPreis As Integer = 6000
    ''' <summary>
    ''' Megapanzerpreis
    ''' </summary>
    ''' <remarks></remarks>
    Const MaximalePreisBoden = 26000
    ''' <summary>
    ''' Wenn wir Einheiten ziehen versuchen wir möglichst wenig Geld zu verlieren!
    ''' </summary>
    ''' <remarks></remarks>
    Const MaximalerSchadensSatz As Single = 0.3#

    Const Ignorierschaden As Single = 10
    Const Gegenschaden As Integer = 2
    Enum Transporter
        Keine
        SeeLuftTransport
        Landtransport
        LuftTransport
        Alle
    End Enum
    Enum KOStärke
        Direkt
        Indirekt
        Luft
        See
        Infantrie
        Boden
        Alle
        SeeLuft
    End Enum

    Public Sub New(ByVal Spieler As ObjektSpieler)
        MyBase.New(Spieler, 0, 1, 0.5#, Besetzungsprioritäten.MeisteEinheiten, GeldTPAngriffsModus.NurGeld, 10, CSng(1 / 3), 5, CSng(1 / 3))
        Select Case Objektverwalter.Spielfeld.GetCommanderWarsModus
            Case CommanderWarsGameModi.AdvanceWarsDC
                NächsteRundeGeld = 14500
            Case Else
                NächsteRundeGeld = 12000
        End Select
        StartNeuerKIThreat()
    End Sub

    ''' <summary>
    ''' Führt die Zug bewegungen der Kinderleichten KI aus. Muahaha und dann Boom.Diese KI kann keine Gebäude bedinnen
    ''' </summary>
    ''' <remarks></remarks>
    Public Overrides Sub KISchleife()
        Objektverwalter.Spielfeld.EingabenErlauben = False
        KIWarten(12)
        CreateVirtuellesLeben()

        While Schleife = False
            MomentaneEinheit = 0
            Select Case KIModusIntern
                Case KIModiIntern.KIStart
                    GabenEinsetzen()
                Case KIModiIntern.StartWarten
                    KIModusIntern = KIModiIntern.GebäudeAngriff
                Case KIModiIntern.GebäudeAngriff
                    GebäudeFeuer()
                Case KIModiIntern.ExternGesteuerteEinheiten
                    ExternGesteurteEinheiten()
                Case KIModiIntern.Besetzen
                    Besetzen()
                Case KIModiIntern.HölliumZiehen
                    HölliumZiehen()
                Case KIModiIntern.Fernkampf
                    FernkampfAngriff()
                Case KIModiIntern.Nahkampf
                    NahkampfAngriff()
                Case KIModiIntern.Nahkampfziehen
                    NahkampfZiehen() 'UV
                Case KIModiIntern.Infanterieziehen
                    InfanterieZiehen() 'UV
                Case KIModiIntern.Fernkampfziehen
                    Fernkampfziehen() 'UV
                Case KIModiIntern.Rückzug
                    Rückzug() 'UV
                Case KIModiIntern.Ration
                    Ration() 'UV
                Case KIModiIntern.TransporterVerladen
                    EinheitenVerladen()
                    KIModusIntern = KIModiIntern.Transproterziehen
                Case KIModiIntern.Transproterziehen
                    TransporterZiehen(EinheitenSortierKriterien.KleinsterBewegungsradius)
                    KIModusIntern = KIModiIntern.Bauen
                Case KIModiIntern.Bauen
                    GetAllBuildings()
                    Bauen() 'UV
                Case KIModiIntern.RundenEndeGabeEinsetzen
                    GabenEinsetzen()
                Case KIModiIntern.RundenEnde
                    RundenEnde()
            End Select
        End While
    End Sub
    ''' <summary>
    ''' So werden zu beginn Gaben einer einfachen KI eingesetzt.
    ''' Es wird nicht überprüft ob der Einsatz der Gabe bzw. Spezialgabe sinnvoll ist.
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub GabenEinsetzen()
        Dim GabeEingesetzt As Boolean = False
        If Spieler.VeränderteWerte.Gabeeinsatz = True Then
            Dim GabefüllstandKO1 As Integer = Spieler.KOS(0).Gabeleiste
            Dim GabefüllstandKO2 As Integer = -1
            If IsNothing(Spieler.KOS(1)) = False Then
                GabefüllstandKO2 = Spieler.KOS(1).Gabeleiste
            End If
            If GabefüllstandKO1 > Spieler.KOS(0).Gabekosten * Spieler.KOS(0).Sternkosten + Spieler.KOS(0).Sternkosten / 2 Then
                If GabefüllstandKO1 >= (Spieler.KOS(0).Gabekosten + Spieler.KOS(0).SpezialgabeKosten) * Spieler.KOS(0).Sternkosten Then
                    If IsNothing(Spieler.KOS(1)) = False Then
                        If GabefüllstandKO2 >= (Spieler.KOS(1).SpezialgabeKosten + Spieler.KOS(1).Gabekosten) * Spieler.KOS(1).Sternkosten Then
                            If Spieler.KOS(1).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenEnde And Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.Beides Then
                            ElseIf Spieler.KOS(1).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenEnde And Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenAnfang Then
                            ElseIf Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenEnde And KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen Then
                                Spieler.KOS(0).Doppelgabe()
                                GabeEingesetzt = True
                            ElseIf Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenAnfang And KIModusIntern = KIModiIntern.KIStart Then
                                'Die Doppelgabe kommt euer untergang ist nah Muahaha
                                Spieler.KOS(0).Doppelgabe()
                                GabeEingesetzt = True
                            ElseIf Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.Beides Then
                                Spieler.KOS(0).Doppelgabe()
                                GabeEingesetzt = True
                            End If
                        ElseIf GabefüllstandKO2 <= (Spieler.KOS(1).SpezialgabeKosten + Spieler.KOS(1).Gabekosten) * Spieler.KOS(1).Sternkosten - Spieler.KOS(1).Sternkosten * 3 Then
                            Select Case Spieler.KOS(0).GabeEinsatzstelle
                                Case ObjektKO.KIGabeEinsatzstellen.RundenAnfang
                                    If KIModusIntern = KIModiIntern.KIStart Then
                                        'Die KI setzt die Spezialgabe ein
                                        If Spieler.KOS(0).KannSpezialGabe Then
                                            Spieler.KOS(0).Spezialgabe()
                                            GabeEingesetzt = True
                                        End If
                                    End If
                                Case ObjektKO.KIGabeEinsatzstellen.RundenEnde
                                    If KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen Then
                                        'Die KI setzt die Spezialgabe ein
                                        If Spieler.KOS(0).KannSpezialGabe Then
                                            Spieler.KOS(0).Spezialgabe()
                                            GabeEingesetzt = True
                                        End If
                                    End If
                                Case ObjektKO.KIGabeEinsatzstellen.Beides
                                    'Die KI setzt die Spezialgabe ein
                                    If Spieler.KOS(0).KannSpezialGabe Then
                                        Spieler.KOS(0).Spezialgabe()
                                        GabeEingesetzt = True
                                    End If
                            End Select
                        End If
                    Else
                        Select Case Spieler.KOS(0).GabeEinsatzstelle
                            Case ObjektKO.KIGabeEinsatzstellen.RundenAnfang
                                If KIModusIntern = KIModiIntern.KIStart Then
                                    'Die KI setzt die Spezialgabe ein
                                    If Spieler.KOS(0).KannSpezialGabe Then
                                        Spieler.KOS(0).Spezialgabe()
                                        GabeEingesetzt = True
                                    End If
                                End If
                            Case ObjektKO.KIGabeEinsatzstellen.RundenEnde
                                If KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen Then
                                    'Die KI setzt die Spezialgabe ein
                                    If Spieler.KOS(0).KannSpezialGabe Then
                                        Spieler.KOS(0).Spezialgabe()
                                        GabeEingesetzt = True
                                    End If
                                End If
                            Case ObjektKO.KIGabeEinsatzstellen.Beides
                                'Die KI setzt die Spezialgabe ein
                                If Spieler.KOS(0).KannSpezialGabe Then
                                    Spieler.KOS(0).Spezialgabe()
                                    GabeEingesetzt = True
                                End If
                        End Select
                    End If
                End If
            ElseIf GabefüllstandKO1 > Spieler.KOS(0).Gabekosten * Spieler.KOS(0).Sternkosten Then
                Select Case Spieler.KOS(0).GabeEinsatzstelle
                    Case ObjektKO.KIGabeEinsatzstellen.RundenAnfang
                        If KIModusIntern = KIModiIntern.KIStart Then
                            'Die KI setzt die Spezialgabe ein
                            If Spieler.KOS(0).KannGabe Then
                                Spieler.KOS(0).Gabe()
                                GabeEingesetzt = True
                            End If
                        End If
                    Case ObjektKO.KIGabeEinsatzstellen.RundenEnde
                        If KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen Then
                            'Die KI setzt die Spezialgabe ein
                            If Spieler.KOS(0).KannGabe Then
                                Spieler.KOS(0).Gabe()
                                GabeEingesetzt = True
                            End If
                        End If
                    Case ObjektKO.KIGabeEinsatzstellen.Beides
                        'Die KI setzt die Spezialgabe ein
                        If Spieler.KOS(0).KannGabe Then
                            Spieler.KOS(0).Gabe()
                            GabeEingesetzt = True
                        End If
                End Select
            End If
        End If
        If KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen And GabeEingesetzt = True Then
            MomentaneEinheit = 0
            KIModusIntern = KIModiIntern.GebäudeAngriff
            'Sonst macht die KI Runden Ende LOL
            KIWarten(2)
            If Schlachtfeld = ObjektSpielfeld.Luftschlacht Then
                Schlachtwechsel(EinheitenSortierKriterien.GrößterBewegungsradius)
            Else
                GetAllUnits(EinheitenSortierKriterien.GrößterBewegungsradius)
            End If
        ElseIf KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen Then
            KIModusIntern = KIModiIntern.RundenEnde
        Else
            KIModusIntern = KIModiIntern.StartWarten
            KIWarten(8)
        End If
    End Sub
    ''' <summary>
    ''' Lässt die Gebäude feuern
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub GebäudeFeuer()
        If IDSBuildingUse() Or Einheiten.Length = 0 Then
            GetAllUnits(EinheitenSortierKriterien.KleinsterBewegungsradius)
        End If
        KIModusIntern = KIModiIntern.ExternGesteuerteEinheiten
    End Sub
    ''' <summary>
    ''' Mit dieser Funktion Suchen sich die Einfachen KI's die Gebäude aus die sie besetzen
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub Besetzen()
        KOEinheitErschaffen()
        GebäudeBesetzen()
        KIModusIntern = KIModiIntern.HölliumZiehen
    End Sub
    ''' <summary>
    ''' Zieht die Hölliums des Spielers
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub HölliumZiehen()
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                If Einheiten(MomentaneEinheit).HatsichBewegt = False Then
                    If Einheiten(MomentaneEinheit).EinheitenID = MovementSorts.HÖLLIUM.tostring.toupper Then
                        'Wir haben ein Höllium zum ziehen.=)
                        Dim Höllium As ObjektEinheit = Einheiten(MomentaneEinheit)
                        Dim WSS As New Wegsuchsystem(Höllium, Höllium.X, Höllium.Y, Höllium.GetMap, -1)
                        Dim Ziel As Point = GetNähestesHölliumZiel(Höllium, WSS)
                        If Ziel.X >= 0 Then
                            Einheitauswählen(Höllium, Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        KIModusIntern = KIModiIntern.Fernkampf
    End Sub
#Region "Fernkampf"
    ''' <summary>
    ''' Führt die Fernkämpfe der einfachen KI aus.
    ''' Diese KI haut mit ihren Fernwaffen in keinem Fall ab.
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub FernkampfAngriff()
        Dim M As ObjektSpielMenü = Objektverwalter.Menü
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                Dim E As ObjektEinheit = Einheiten(MomentaneEinheit)
                If E.HatsichBewegt = False Then
                    If E.MaximaleReichweite > 1 Then
                        Dim WSS As Wegsuchsystem = CreateWSS(E)
                        'OH je  das wird noch komplikate
                        If E.CanIndirectMoveAndFire And Spieler.KOS(0).FireandMove = True Then
                            Dim Feld As Point = GetFernkampfOpfer(E, GetAllFernKampfFelderGebäude(E, E.X, E.Y, True))
                            If Feld.X >= 0 Then
                                Einheitauswählen(E, New Point(E.X, E.Y), KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Feld.X, Feld.Y, Schlachtfeld), WSS)
                                Dim Felder As Point2 = GetFernkampfOpferMitBewegung(E, WSS)
                                If Felder.Point1.X >= 0 And Felder.Point2.X >= 0 Then
                                    'So wir haben ein Opfer.
                                    Einheitauswählen(E, Felder.Point1, KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Felder.Point2.X, Felder.Point2.Y, Schlachtfeld), WSS)
                                    CalculatePotentiellenGegenschaden(E, Felder.Point1, True)
                                Else
                                    'wir haben unser Opfer angegriffen jetzt sollten wir die Einheit noch ziehen.
                                    Dim Ziel As Point = GetNähestesFernkampffeldSicher(E, WSS)
                                    If Ziel.X >= 0 Then
                                        NächsterBefehl(Ziel, Nothing, KIModiExtern.Warten, WSS, 4)
                                        CalculatePotentiellenGegenschaden(E, Ziel, True)
                                    Else
                                        Ziel = ZumNähestenHQZiehen(E, WSS)
                                        If Ziel.X > 0 Then
                                            Einheitauswählen(E, Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                                            CalculatePotentiellenGegenschaden(E, Ziel, True)
                                            EinheitGezogenVonVorneStarten()
                                        Else
                                            EinheitAbwählen()
                                            CalculatePotentiellenGegenschaden(E, New Point(E.X, E.Y), True)
                                        End If
                                    End If
                                End If
                            Else
                                'Ein Angriff ziehen und Feuern wie beim Nahkampf
                                Dim Felder As Point2 = GetFernkampfOpferMitBewegung(E, WSS)
                                If Felder.Point1.X >= 0 And Felder.Point2.X >= 0 Then
                                    'So wir haben ein Opfer.
                                    Einheitauswählen(E, Felder.Point1, KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Felder.Point2.X, Felder.Point2.Y, Schlachtfeld), WSS)
                                    CalculatePotentiellenGegenschaden(E, Felder.Point1, True)
                                End If
                            End If
                        ElseIf E.CanIndirectMoveAndFire Then
                            'Ein Angriff ziehen und Feuern wie beim Nahkampf
                            Dim Felder As Point2 = GetFernkampfOpferMitBewegung(E, WSS)
                            If Felder.Point1.X >= 0 And Felder.Point2.X >= 0 Then
                                'So wir haben ein Opfer.
                                Einheitauswählen(E, Felder.Point1, KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Felder.Point2.X, Felder.Point2.Y, Schlachtfeld), WSS)
                                CalculatePotentiellenGegenschaden(E, Felder.Point1, True)
                            End If
                        ElseIf Spieler.KOS(0).FireandMove = True Then
                            'Wir suchen uns ein Opfer
                            Dim Feld As Point = GetFernkampfOpfer(E, GetAllFernKampfFelderGebäude(E, E.X, E.Y, True))
                            If Feld.X >= 0 Then
                                Einheitauswählen(E, New Point(E.X, E.Y), KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Feld.X, Feld.Y, Schlachtfeld), WSS)
                                'wir haben unser Opfer angegriffen jetzt sollten wir die Einheit noch ziehen.
                                Dim Ziel As Point = GetNähestesFernkampffeldSicher(E, WSS)
                                If Ziel.X >= 0 Then
                                    NächsterBefehl(Ziel, Nothing, KIModiExtern.Warten, WSS, 4)
                                    CalculatePotentiellenGegenschaden(E, Ziel, True)
                                Else
                                    Ziel = ZumNähestenHQZiehen(E, WSS)
                                    If Ziel.X > 0 Then
                                        Einheitauswählen(E, Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                                        CalculatePotentiellenGegenschaden(E, Ziel, True)
                                        EinheitGezogenVonVorneStarten()
                                    Else
                                        EinheitAbwählen()
                                        CalculatePotentiellenGegenschaden(E, New Point(E.X, E.Y), True)
                                    End If
                                End If
                            End If
                        Else
                            'Das ist mir die liebste und einfachst Situation Uff. Wir können nur Feuern oder ziehen.
                            Dim Feld As Point = GetBestesFernkampfOpferFirstFernwaffen(E, GetAllFernKampfFelderGebäude(E, E.X, E.Y, True))
                            If Feld.X >= 0 Then
                                Dim Opfer As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(Feld.X, Feld.Y, Schlachtfeld)
                                If Opfer Is Nothing Then Opfer = ObjektLadeklasse.NewEinheit("ABPZ", 0, Feld.X, Feld.Y, 100, False)
                                Einheitauswählen(E, New Point(E.X, E.Y), KIModiExtern.Angriff, Opfer, WSS, 4)
                                CalculatePotentiellenGegenschaden(E, New Point(E.X, E.Y), True)
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        KIModusIntern = KIModiIntern.Nahkampf
    End Sub
    ''' <summary>
    ''' Gibt das beste Opfer dieser Einheit von der momentanen Position zurück. Berechnet nach dem Geldschaden aber primäres Ziel sind Fernwaffen.
    ''' </summary>
    ''' <param name="Einheit"></param>
    ''' <returns>Gibt (-1,-1) zurück wenn kein Opfer gefunden</returns>
    ''' <remarks></remarks>
    Protected Overrides Function GetBestesFernkampfOpferFirstFernwaffen(ByVal Einheit As ObjektEinheit, ByVal Opfer() As Point) As Point
        If Opfer.Length > 0 Then
            Dim MomentanesOpfer As Integer = -1
            Dim MomentanerSchaden As Integer = 0
            Dim Deckung As Integer = 99
            Dim Fernwaffe As Boolean = False 'Haben wir schon eine Fernwaffe gefunden?
            For I = 0 To Opfer.Length - 1
                Dim UnserOpfer As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(Opfer(I).X, Opfer(I).Y, Schlachtfeld)
                If Not UnserOpfer Is Nothing Then
                    Dim UrspVLE As Single = Einheit.VirtuellesLeben
                    Dim UrspVLO As Single = UnserOpfer.VirtuellesLeben
                    Dim Schaden As Integer() = CalculatePotentielleGeldVerluste(Einheit, Einheit.X, Einheit.Y, UnserOpfer, UnserOpfer.X, UnserOpfer.Y)
                    Dim MöglSchaden As Integer = Schaden(0)
                    If UnserOpfer.MinimaleReichweite > 1 Then
                        'Das Opfer ist eine Fernwaffe, diese sollen höher gewichtet werden!
                        MöglSchaden *= 3
                    Else
                        MöglSchaden *= 2
                    End If
                    If Not GegenschadenIgnorieren And Schaden(1) < 0 Then
                        MöglSchaden += CalculatePotentiellenGegenschaden(Einheit, New Point(Einheit.X, Einheit.Y), False)
                    End If
                    MöglSchaden *= -1

                    'Die Deckung des Opfers in dem Fall!
                    Dim DeckungMom As Integer = Spieler.GetDeffensivSterne(UnserOpfer, Objektverwalter.Spielfeld.Landschaften(UnserOpfer.X, UnserOpfer.Y, Schlachtfeld))
                    If MöglSchaden >= MinimalerGeldschaden Then
                        If MöglSchaden > MomentanerSchaden Then
                            MomentanerSchaden = MöglSchaden
                            MomentanesOpfer = I
                            Deckung = DeckungMom
                        ElseIf MöglSchaden = MomentanerSchaden And DeckungMom < Deckung Then
                            MomentanerSchaden = MöglSchaden 'lieber die Einheit angreifen, die weniger Deckung hat, bevor sie noch irgendwohingeht, wo sie dann wieder mehr Deckung hat.
                            MomentanesOpfer = I
                            Deckung = DeckungMom
                        ElseIf MöglSchaden = MomentanerSchaden And DeckungMom = Deckung And Zufallszahl(0, 1) = 0 Then
                            MomentanerSchaden = MöglSchaden
                            MomentanesOpfer = I
                            Deckung = DeckungMom
                        End If
                    End If

                    Einheit.VirtuellesLeben = UrspVLE
                    UnserOpfer.VirtuellesLeben = UrspVLO
                Else
                    'Wir greifen ein Gebäude oder eine Landschaft an.
                    If Objektverwalter.Spielfeld.Landschaften(Opfer(I).X, Opfer(I).Y, Schlachtfeld).Leben > 0 Then
                        If MomentanerSchaden = 0 Then
                            If MomentanesOpfer < 0 Then
                                MomentanesOpfer = I
                            ElseIf Zufallszahl(0, 1) = 0 Then
                                MomentanesOpfer = I
                            End If
                        End If
                    Else
                        Dim G As ObjektGebäude = Objektverwalter.Spielfeld.Landschaften(Opfer(I).X, Opfer(I).Y, Schlachtfeld).Gebäude
                        Dim Schaden As Integer = ObjektLadeklasse.GetGebäudeKosten(G.GebäudeID, G.Spieler) / G.GetMaxLeben * Tabellenverwalter.GetWert(Einheit.Waffe2, "Gebäude")
                        If Schaden > MomentanerSchaden Then
                            MomentanerSchaden = Schaden
                            MomentanesOpfer = I
                        ElseIf Schaden = MomentanerSchaden And Zufallszahl(0, 1) = 1 Then
                            MomentanerSchaden = Schaden
                            MomentanesOpfer = I
                        End If
                    End If
                End If
            Next
            If MomentanesOpfer >= 0 Then
                Return Opfer(MomentanesOpfer)
            Else
                Return New Point(-1, -1)
            End If
        Else
            Return New Point(-1, -1)
        End If
    End Function
    ''' <summary>
    ''' Gibt das beste Opfer dieser Einheit von der momentanen Position zurück. Berechnet nach dem Geldschaden aber primäres Ziel sind Fernwaffen.
    ''' </summary>
    ''' <param name="Einheit"></param>
    ''' <returns>Gibt (-1,-1) zurück wenn kein Opfer gefunden</returns>
    ''' <remarks></remarks>
    Private Function GetFernkampfOpfer(ByVal Einheit As ObjektEinheit, ByVal Opfer() As Point) As Point
        If Opfer.Length > 0 Then
            Dim MomentanesOpfer As Integer = -1
            Dim MomentanerSchaden As Integer = 0
            Dim Deckung As Integer = 99
            Dim Fernwaffe As Boolean = False 'Haben wir schon eine Fernwaffe gefunden?
            For I = 0 To Opfer.Length - 1
                Dim UnserOpfer As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(Opfer(I).X, Opfer(I).Y, Schlachtfeld)
                If Not UnserOpfer Is Nothing Then
                    Dim ATKLeben As Single = Einheit.Leben
                    Dim DefLeben As Single = UnserOpfer.Leben
                    Dim MöglSchaden As Single = Objektverwalter.Schadensberechnung(Einheit, Einheit.X, Einheit.Y, UnserOpfer.X, UnserOpfer.Y, ATKLeben, DefLeben, True, Einheit.GetSpieler.GetGlückPech(Einheit.X, Einheit.Y).X * Glücksfaktor, UnserOpfer)(0)
                    If MöglSchaden > UnserOpfer.Leben Then MöglSchaden = UnserOpfer.Leben
                    MöglSchaden = UnserOpfer.GetKosten * getKP(MöglSchaden) / 10

                    If UnserOpfer.MinimaleReichweite > 1 Then
                        'Das Opfer ist eine Fernwaffe, diese sollen höher gewichtet werden!
                        MöglSchaden *= 2
                    End If
                    MöglSchaden *= -1

                    'Die Deckung des Opfers in dem Fall!
                    Dim DeckungMom As Integer = Spieler.GetDeffensivSterne(UnserOpfer, Objektverwalter.Spielfeld.Landschaften(UnserOpfer.X, UnserOpfer.Y, Schlachtfeld))
                    If MöglSchaden >= MinimalerGeldschaden Then
                        If MöglSchaden > MomentanerSchaden Then
                            MomentanerSchaden = MöglSchaden
                            MomentanesOpfer = I
                            Deckung = DeckungMom
                        ElseIf MöglSchaden = MomentanerSchaden And DeckungMom < Deckung Then
                            MomentanerSchaden = MöglSchaden 'lieber die Einheit angreifen, die weniger Deckung hat, bevor sie noch irgendwohingeht, wo sie dann wieder mehr Deckung hat.
                            MomentanesOpfer = I
                            Deckung = DeckungMom
                        ElseIf MöglSchaden = MomentanerSchaden And DeckungMom = Deckung And Zufallszahl(0, 1) = 0 Then
                            MomentanerSchaden = MöglSchaden
                            MomentanesOpfer = I
                            Deckung = DeckungMom
                        End If
                    End If

                Else
                    'Wir greifen ein Gebäude oder eine Landschaft an.
                    If Objektverwalter.Spielfeld.Landschaften(Opfer(I).X, Opfer(I).Y, Schlachtfeld).Leben > 0 Then
                        If MomentanerSchaden = 0 Then
                            If MomentanesOpfer < 0 Then
                                MomentanesOpfer = I
                            ElseIf Zufallszahl(0, 1) = 0 Then
                                MomentanesOpfer = I
                            End If
                        End If
                    Else
                        Dim G As ObjektGebäude = Objektverwalter.Spielfeld.Landschaften(Opfer(I).X, Opfer(I).Y, Schlachtfeld).Gebäude
                        Dim Schaden As Integer = ObjektLadeklasse.GetGebäudeKosten(G.GebäudeID, G.Spieler) / G.GetMaxLeben * Tabellenverwalter.GetWert(Einheit.Waffe2, "Gebäude")
                        If Schaden > MomentanerSchaden Then
                            MomentanerSchaden = Schaden
                            MomentanesOpfer = I
                        ElseIf Schaden = MomentanerSchaden And Zufallszahl(0, 1) = 1 Then
                            MomentanerSchaden = Schaden
                            MomentanesOpfer = I
                        End If
                    End If
                End If
            Next
            If MomentanesOpfer >= 0 Then
                Return Opfer(MomentanesOpfer)
            Else
                Return New Point(-1, -1)
            End If
        Else
            Return New Point(-1, -1)
        End If
    End Function
    ''' <summary>
    ''' Let's see which Unit we should attack while moving this Indirect Unit
    ''' </summary>
    ''' <param name="E"></param>
    ''' <param name="WSS"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function GetFernkampfOpferMitBewegung(ByVal E As ObjektEinheit, ByRef WSS As Wegsuchsystem) As Point2
        Dim Opfer() As Point2 = GetAllFernkampfFeldermitBewegungNormal(E, WSS)
        Dim MomentanesOpfer As Integer = -1
        If Opfer.Length > 0 Then

            Dim MomentanerSchaden As Integer = 0
            Dim Deckung As Integer
            For I = 0 To Opfer.Length - 1
                Dim UnserOpfer As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(Opfer(I).Point2.X, Opfer(I).Point2.Y, Schlachtfeld)
                If UnserOpfer IsNot Nothing Then
                    Dim UrspVLE As Single = E.VirtuellesLeben
                    Dim UrspVLO As Single = UnserOpfer.VirtuellesLeben
                    Dim Schaden As Integer() = CalculatePotentielleGeldVerluste(E, Opfer(I).Point1.X, Opfer(I).Point1.Y, UnserOpfer, UnserOpfer.X, UnserOpfer.Y)
                    Dim MöglSchaden As Integer = Schaden(0)

                    If UnserOpfer.MinimaleReichweite > 1 Then
                        'Das Opfer ist eine Fernwaffe, diese sollen höher gewichtet werden!
                        MöglSchaden *= 3
                    Else
                        MöglSchaden *= 2
                    End If
                    If Not GegenschadenIgnorieren And Schaden(1) < 0 Then
                        MöglSchaden += CalculatePotentiellenGegenschaden(E, New Point(Opfer(I).Point1.X, Opfer(I).Point1.Y), False)
                    End If
                    MöglSchaden *= -1

                    'Die Deckung des Opfers in dem Fall!
                    Dim DeckungMom As Integer = Spieler.GetDeffensivSterne(UnserOpfer, Objektverwalter.Spielfeld.Landschaften(UnserOpfer.X, UnserOpfer.Y, Schlachtfeld))
                    If MöglSchaden >= MinimalerGeldschaden Then
                        If MöglSchaden > MomentanerSchaden Then
                            MomentanerSchaden = MöglSchaden
                            MomentanesOpfer = I
                            Deckung = DeckungMom
                        ElseIf MöglSchaden = MomentanerSchaden And DeckungMom < Deckung Then
                            MomentanerSchaden = MöglSchaden 'lieber die Einheit angreifen, die weniger Deckung hat, bevor sie noch irgendwohingeht, wo sie dann wieder mehr Deckung hat.
                            MomentanesOpfer = I
                            Deckung = DeckungMom
                        ElseIf MöglSchaden = MomentanerSchaden And DeckungMom = Deckung And Zufallszahl(0, 1) = 0 Then
                            MomentanerSchaden = MöglSchaden
                            MomentanesOpfer = I
                            Deckung = DeckungMom
                        End If
                    End If
                    E.VirtuellesLeben = UrspVLE
                    UnserOpfer.VirtuellesLeben = UrspVLO
                Else
                    If Objektverwalter.Spielfeld.Landschaften(Opfer(I).Point2.X, Opfer(I).Point2.Y, Schlachtfeld).Leben > 0 Then
                        If CalculatePotentiellenGegenschaden(E, Opfer(I).Point1, False) <= 0 Then
                            If MomentanerSchaden = 0 Then
                                If MomentanesOpfer <> 0 Then
                                    If Zufallszahl(0, 1) = 0 Then
                                        MomentanesOpfer = I
                                    End If
                                Else
                                    MomentanesOpfer = I
                                End If
                            End If
                        End If
                    Else
                        Dim G As ObjektGebäude = Objektverwalter.Spielfeld.Landschaften(Opfer(I).Point2.X, Opfer(I).Point2.Y, Schlachtfeld).Gebäude
                        Dim Schaden As Integer = ObjektLadeklasse.GetGebäudeKosten(G.GebäudeID, G.Spieler) / G.GetMaxLeben * Tabellenverwalter.GetWert(E.Waffe2, "Gebäude") - CalculatePotentiellenGegenschaden(E, Opfer(I).Point1, False)
                        If Schaden > MomentanerSchaden Then
                            MomentanerSchaden = Schaden
                            MomentanesOpfer = I
                        ElseIf Schaden = MomentanerSchaden And Zufallszahl(0, 1) = 1 Then
                            MomentanerSchaden = Schaden
                            MomentanesOpfer = I
                        End If
                    End If
                End If
            Next
        End If
        If MomentanesOpfer >= 0 Then
            Return Opfer(MomentanesOpfer)
        Else
            Return New Point2(New Point(-1, -1), New Point(-1, -1))
        End If
    End Function
    ''' <summary>
    ''' All units this Indirect Unit can attack!
    ''' </summary>
    ''' <param name="Einheit"></param>
    ''' <param name="WSS"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetAllFernkampfFeldermitBewegungNormal(ByVal Einheit As ObjektEinheit, Optional ByRef WSS As Wegsuchsystem = Nothing) As Point2()
        Dim Felder As New Stack(Of Point2)
        If Einheit.MaximaleReichweite > 1 Then
            Dim Bewegunspunkte As Integer = Einheit.GetMovementRange
            If WSS Is Nothing Then
                If Bewegunspunkte <= Einheit.Treibstoff Then
                    WSS = New Wegsuchsystem(Einheit, Einheit.X, Einheit.Y, Einheit.GetMap, Bewegunspunkte)
                ElseIf Einheit.Treibstoff = -1 Then
                    WSS = New Wegsuchsystem(Einheit, Einheit.X, Einheit.Y, Einheit.GetMap, Bewegunspunkte)
                Else
                    WSS = New Wegsuchsystem(Einheit, Einheit.X, Einheit.Y, Einheit.GetMap, Einheit.Treibstoff)
                End If
            End If
            For Y1 = 0 To Objektverwalter.Spielfeld.Höhe - 1
                For X1 = 0 To Objektverwalter.Spielfeld.Breite - 1
                    Dim Kosten As Integer = WSS.getBewegungspunktekosten(X1, Y1)
                    Dim neuerPunkt As Point = New Point(X1, Y1)
                    If Kosten >= 0 And Kosten <= Bewegunspunkte Then
                        If neuerPunkt.X >= 0 And neuerPunkt.X < Objektverwalter.Spielfeld.Breite And neuerPunkt.Y >= 0 And neuerPunkt.Y < Objektverwalter.Spielfeld.Höhe Then
                            If IsFeldLeer(neuerPunkt.X, neuerPunkt.Y, Einheit) = True Then
                                'So dieses Feld kann betreten werden und jetzt schießen wir von ihm aus.
                                Dim Felder2 As Point() = GetAllFernKampfFelderGebäude(Einheit, neuerPunkt.X, neuerPunkt.Y, True)
                                For Each Feld In Felder2
                                    Felder.Push(New Point2(neuerPunkt, Feld))
                                Next
                            End If
                        End If
                    End If
                Next
            Next
        End If
        Return Felder.ToArray
    End Function
#End Region
#Region "Nahkampf"
    ''' <summary>
    ''' So ziehen einfache KI's in den Nahkampf
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub NahkampfAngriff()
        CreateVirtuellesLeben()
        While MomentaneEinheit < Einheiten.Length
            Dim Einheit As ObjektEinheit = Einheiten(MomentaneEinheit)
            If ExistUnit(Einheit) = True Then
                If Einheit.IsUsingUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) = True Then
                    If Einheit.KannBesetzen = False Then
                        If Einheit.MinimaleReichweite = 1 Or Not Einheit.Waffe1 = "Keine" Then
                            Dim WSS As Wegsuchsystem = CreateWSS(Einheit)
                            Dim Feld As Point2 = GetBestesNahkampfOpferFeldSicher(Einheit, WSS, GetAllNahKampffelder(Einheit, True, WSS))
                            If Feld.Point1.X >= 0 And Feld.Point2.X >= 0 Then
                                Einheitauswählen(Einheit, Feld.Point1, KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Feld.Point2.X, Feld.Point2.Y, Schlachtfeld), WSS, 4)
                                CalculatePotentiellenGegenschaden(Einheit, Feld.Point1, True)
                                EinheitGezogenVonVorneStarten()
                                Exit Sub
                            Else
                                Feld = GetBestesNahkampfGebäude(Einheit, WSS)
                                If Feld.Point1.X >= 0 And Feld.Point2.X >= 0 Then
                                    Einheitauswählen(Einheit, Feld.Point1, KIModiExtern.Angriff, New EinheitAmphibienpanzer(0, Feld.Point2.X, Feld.Point2.Y), WSS, 4)
                                    CalculatePotentiellenGegenschaden(Einheit, Feld.Point1, True)
                                    EinheitGezogenVonVorneStarten()
                                    Exit Sub
                                End If
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        KIModusIntern = KIModiIntern.Nahkampfziehen
    End Sub
    ''' <summary>
    ''' Gibt das beste Opfer dieser Einheit von der momentanen Position zurück.
    ''' </summary>
    ''' <param name="Einheit"></param>
    ''' <returns>Gibt (-1,-1) zurück wenn kein Opfer gefunden</returns>
    ''' <remarks></remarks>
    Function GetBestesNahkampfOpferFeldSicher(ByVal Einheit As ObjektEinheit, ByRef WSS As Wegsuchsystem, ByVal Opfer() As Point2) As Point2
        If Opfer.Length > 0 Then
            Dim MomentanesOpfer As Integer = -1
            Dim MomentanerSchaden As Single = 0
            'Dim PotentiellerGegenschaden As Single = -100
            Dim Deckung As Integer = 0
            Dim Fernwaffen As Integer = False
            For I = 0 To Opfer.Length - 1
                Dim UnserOpfer As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(Opfer(I).Point2.X, Opfer(I).Point2.Y, Schlachtfeld)
                Dim UrspVLE As Single = Einheit.VirtuellesLeben
                Dim UrspVLO As Single = UnserOpfer.VirtuellesLeben

                'Wir berechnen wie viel Geldschaden wir anrichten würden
                Dim Schaden As Integer() = CalculatePotentielleGeldVerluste(Einheit, Opfer(I).Point1.X, Opfer(I).Point1.Y, UnserOpfer, UnserOpfer.X, UnserOpfer.Y)
                Dim MöglSchaden As Integer = Schaden(0)
                If Not GegenschadenIgnorieren And Schaden(1) < 0 Then
                    MöglSchaden *= Gegenschaden
                    MöglSchaden += CalculatePotentiellenGegenschaden(Einheit, New Point(Opfer(I).Point1.X, Opfer(I).Point1.Y), False)
                End If
                MöglSchaden *= -1

                Dim DeckungMom As Integer = Spieler.GetDeffensivSterne(UnserOpfer, Objektverwalter.Spielfeld.Landschaften(Opfer(I).Point1.X, Opfer(I).Point1.Y, Schlachtfeld))
                'If IsFernZielFürEinheit(Einheit, Opfer(I).Point1.X, Opfer(I).Point1.Y) Then
                '    Schaden -= 1 '???
                'End If
                If MöglSchaden >= MinimalerGeldschaden Then
                    If MöglSchaden > MomentanerSchaden Then
                        MomentanerSchaden = MöglSchaden
                        MomentanesOpfer = I
                        Deckung = DeckungMom
                    ElseIf MöglSchaden = MomentanerSchaden And DeckungMom > Deckung Then
                        MomentanerSchaden = MöglSchaden
                        MomentanesOpfer = I
                        Deckung = DeckungMom
                    ElseIf MöglSchaden = MomentanerSchaden And DeckungMom = Deckung And Zufallszahl(0, 1) = 0 Then
                        MomentanerSchaden = MöglSchaden
                        MomentanesOpfer = I
                        Deckung = DeckungMom
                    End If
                End If

                Einheit.VirtuellesLeben = UrspVLE
                UnserOpfer.VirtuellesLeben = UrspVLO
            Next
            If MomentanesOpfer < 0 Then
                Return New Point2(New Point(-1, -1), New Point(-1, -1))
            Else
                Return Opfer(MomentanesOpfer)
            End If
        Else
            Return New Point2(New Point(-1, -1), New Point(-1, -1))
        End If
    End Function
    'Da oben (nat auch beim Fernkampf) die Deckung
    'PotentiellerGegenschaden ausführen. [Fernkampf | InfanterieZiehen] unvollständig!
    'UNVOLLSTÄNDIG!!! Gebäude werden noch nicht berücksichtigt!
    ''' <summary>
    ''' Gibt den Möglichen Geldschaden zurück. Dabei wird von einem Angriff immer der pot Geldschaden der Einheit - dem pot Geldschaden des Angreifers gerechnet. Das natürlich über alle möglichen Angreifer geloopt!
    ''' </summary>
    ''' <param name="Einheit">Die Einheit, die von allen angegriffen werden darf!</param>
    ''' <param name="Position">Die Position, welche die Einheit inne hat, wenn sie angegriffen wird.</param>
    ''' <param name="DoPräventivSchaden">Wenn = True, dann wird ein Teil des Schaden, den die Einheiten erleiden, die die Einheit angreifen, tatsächlich abgespeichert. (Natürlich wird grundsätlich nur mit den Virtuellen und nicht mit dem Tatsächlichen Leben gerechnet!)</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CalculatePotentiellenGegenschaden(ByVal Einheit As ObjektEinheit, ByVal Position As Point, ByVal DoPräventivSchaden As Boolean) As Integer
        Dim PotGegenSchaden As Integer = 0


        For Each Unit In Objektverwalter.Spielfeld.Einheiten
            If Unit IsNot Nothing Then
                If Unit.GetMap = Einheit.GetMap Then
                    If Unit.GetSpieler.Team <> Einheit.GetSpieler.Team Then
                        If Unit.isSichtbar(Unit.GetSpieler.Team) Then
                            Dim Wetter As ObjektSpielfeld.Wetterarten = Objektverwalter.Spielfeld.Regeln.GetWetterBeiSpieler(Unit.Spieler)
                            If Unit.Bewegungsart = MovementSorts.Höllium.tostring Then
                                Dim WSS As New Wegsuchsystem(Unit, Unit.GetMovementRange(Wetter))
                                Dim Bew As Integer = WSS.getBewegungspunktekosten(Position.X, Position.Y, Einheit.GetMap)
                                If Bew >= 0 Then
                                    If Bew <= Unit.GetMovementRange Then
                                        Dim KEinheit As Integer = (Einheit.Kosten * Einheit.GetSpieler.Teurungsrate(Einheit, Position.X, Position.Y)) * (Einheit.VirtuellesLeben / 100) 'Naja das Höllium macht halt einfach, alles übrige Leben weg ;) eigentlich nicht schwer.
                                        If Unit.VirtuellerMeistSchaden < KEinheit Then
                                            PotGegenSchaden += KEinheit
                                            If DoPräventivSchaden Then
                                                If Unit.VirtuellerMeistSchaden < KEinheit Then
                                                    Unit.VirtuellerMeistSchaden = KEinheit
                                                End If
                                            End If
                                        End If
                                        Continue For
                                    End If
                                End If
                            End If
                            If Unit.IsAttackable(Einheit, True) Then
                                If Unit.GetDistance(Position) <= Unit.GetMovementRange(Wetter) + 1 Then
                                    If Unit.IsNahkampfEinheit Then
                                        Dim WSS As New Wegsuchsystem(Unit, Unit.GetMovementRange(Wetter), , True)
                                        Dim L As ObjektLandschaft = Nothing
                                        L = Wegsuchsystem.getFeldRundrum(Position.X, Position.Y, Einheit.GetMap, 1, 1, L, Objektverwalter.Spielfeld)
                                        Do Until L Is Nothing
                                            Dim Bew As Integer = WSS.getBewegungspunktekosten(L.KooX, L.KooY, Einheit.GetMap)
                                            If Bew >= 0 Then
                                                If Bew <= Unit.GetMovementRange Then
                                                    Dim ATKLeben As Single = Unit.VirtuellesLeben
                                                    Dim DefLeben As Single = Einheit.VirtuellesLeben
                                                    Dim VerursachterSchaden() As Single = Objektverwalter.Schadensberechnung(Unit, L.KooX, L.KooY, Position.X, Position.Y, ATKLeben, DefLeben, True, Unit.GetSpieler.GetGlückPech(L.KooX, L.KooY).X * Glücksfaktor, Einheit)
                                                    If VerursachterSchaden(0) > Ignorierschaden Then 'Bei so wenig Gegenschaden werden wir nicht angegriffen!
                                                        If DefLeben < 0 Then DefLeben = 0
                                                        Dim GegenSchaden() As Single = Objektverwalter.Schadensberechnung(Einheit, Position.X, Position.Y, L.KooX, L.KooY, DefLeben, ATKLeben, True, Einheit.GetSpieler.GetGlückPech(Position.X, Position.Y).X * Glücksfaktor, Unit)
                                                        If ATKLeben < 0 Then ATKLeben = 0
                                                        Dim KEinheit As Integer = (Einheit.Kosten * Einheit.GetSpieler.Teurungsrate(Einheit, Position.X, Position.Y)) * ((Einheit.Leben - DefLeben) / 100)
                                                        Dim KUnit As Integer = (Unit.Kosten * Unit.GetSpieler.Teurungsrate(Unit, L.KooX, L.KooY)) * ((Unit.Leben - ATKLeben) / 100)
                                                        If KUnit > KEinheit Then
                                                            'Die Kosten für Unit ist größer, als die Kosten für Einheit. Das heißt, wir müssen uns nicht fürchten, wenn uns Unit angreift, selber schuld ;)
                                                        Else
                                                            'Hmm die Kosten die wir reinstecken müssen sind mehr, als die vom Gegner, das heißt der Gegner ist eine potentielle Gefahrenquelle!
                                                            If Unit.VirtuellerMeistSchaden < KEinheit - KUnit Then
                                                                PotGegenSchaden += KEinheit - KUnit
                                                                Einheit.VirtuellesLeben = DefLeben
                                                                If DoPräventivSchaden Then
                                                                    If Unit.VirtuellerMeistSchaden < KEinheit - KUnit Then
                                                                        Unit.VirtuellerMeistSchaden = KEinheit - KUnit
                                                                    End If
                                                                End If
                                                            End If
                                                        End If
                                                        Continue For
                                                    Else
                                                        Continue For
                                                    End If
                                                End If
                                            End If
                                            L = Wegsuchsystem.getFeldRundrum(Position.X, Position.Y, Einheit.GetMap, 1, 1, L, Objektverwalter.Spielfeld)
                                        Loop
                                        '   Objektverwalter.Schadensberechnung()   '0=Schaden 1=waffe (Prim/sekundär|1/2) 
                                    End If
                                End If
                                If Unit.MaximaleReichweite > 1 Then
                                    Dim Dis As Integer = Unit.GetDistance(Position)
                                    If Dis <= Unit.GetMaximalReichweite(Wetter) Then
                                        If Dis >= Unit.MinimaleReichweite Then
                                            Dim ATKLeben As Single = Unit.VirtuellesLeben
                                            Dim DefLeben As Single = Einheit.VirtuellesLeben
                                            Dim VerursachterSchaden() As Single = Objektverwalter.Schadensberechnung(Unit, Unit.X, Unit.Y, Position.X, Position.Y, ATKLeben, DefLeben, True, Unit.GetSpieler.GetGlückPech(Unit.X, Unit.Y).X * Glücksfaktor, Einheit)
                                            If DefLeben < 0 Then DefLeben = 0
                                            Dim GegenSchaden() As Single = Objektverwalter.Schadensberechnung(Einheit, Position.X, Position.Y, Unit.X, Unit.Y, DefLeben, ATKLeben, True, Einheit.GetSpieler.GetGlückPech(Position.X, Position.Y).X * Glücksfaktor, Unit)
                                            If ATKLeben < 0 Then ATKLeben = 0
                                            Dim KEinheit As Integer = (Einheit.Kosten * Einheit.GetSpieler.Teurungsrate(Einheit, Position.X, Position.Y)) * ((Einheit.Leben - DefLeben) / 100)
                                            Dim KUnit As Integer = (Unit.Kosten * Unit.GetSpieler.Teurungsrate(Unit, Unit.X, Unit.Y)) * ((Unit.Leben - ATKLeben) / 100)
                                            If KUnit < KEinheit Then
                                                'Hmm die Kosten die wir reinstecken müssen sind mehr, als die vom Gegner, das heißt der Gegner ist eine potentielle Gefahrenquelle!
                                                If Unit.VirtuellerMeistSchaden < KEinheit - KUnit Then
                                                    PotGegenSchaden += KEinheit - KUnit
                                                    Einheit.VirtuellesLeben = DefLeben
                                                    If DoPräventivSchaden Then
                                                        If Unit.VirtuellerMeistSchaden < KEinheit - KUnit Then
                                                            Unit.VirtuellerMeistSchaden = KEinheit - KUnit
                                                        End If
                                                    End If
                                                End If
                                            End If
                                            Continue For
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        Next
        Return PotGegenSchaden
    End Function
    ''' <summary>
    ''' Rechnet aus, wieviel Geldschaden entsteht. Das heißt die Differenz. Den Schaden, welchen der Angreifer nimmt Minus den Schaden, den der Verteidiger nimmt. Das Leben, was die beiden Einheiten dann noch vermutlich haben, wird unter Virtuelles Leben gespeichert!
    ''' </summary>
    ''' <param name="Angreifer">Der Angreifer</param>
    ''' <param name="AX">Angreifer KooX</param>
    ''' <param name="AY">Angreifer KooY</param>
    ''' <param name="Verteidiger">Der Verteidiger</param>
    ''' <param name="VX">Verteidiger KooX</param>
    ''' <param name="VY">Verteidiger KooY</param>
    ''' <returns>Stelle 0:Schaden; Stelle 2: >0 Gegner zerstört oder 0> Feind hat überlebt!</returns>
    ''' <remarks></remarks>
    Public Function CalculatePotentielleGeldVerluste(ByVal Angreifer As ObjektEinheit, ByVal AX As Integer, ByVal AY As Integer, ByVal Verteidiger As ObjektEinheit, ByVal VX As Integer, ByVal VY As Integer) As Integer()
        Dim ATKLeben As Single = Angreifer.Leben
        Dim DefLeben As Single = Verteidiger.Leben
        Dim VerursachterSchaden() As Single = Objektverwalter.Schadensberechnung(Angreifer, AX, AY, VX, VY, ATKLeben, DefLeben, True, Angreifer.GetSpieler.GetGlückPech(AX, AY).X * Glücksfaktor, Verteidiger)
        Dim BesetzungsBonus As Single = calculateBesetzungsbonus(Verteidiger, DefLeben)


        If DefLeben <= 0 Then 'Das vernichten einer Einheit bringt einen kleinen Bonus!
            DefLeben = 0
            Dim KVerteidiger As Integer = (Verteidiger.Kosten * Verteidiger.GetSpieler.Teurungsrate(Verteidiger, VX, VY)) * ((Verteidiger.Leben - DefLeben) / 100)
            Angreifer.VirtuellesLeben = ATKLeben
            Verteidiger.VirtuellesLeben = DefLeben
            Return New Integer() {-KVerteidiger * 2 * BesetzungsBonus, 1}
        ElseIf Distance(New Point(AX, AY), New Point(VX, VY)) > 1 Then
            Dim KVerteidiger As Integer = (Verteidiger.Kosten * Verteidiger.GetSpieler.Teurungsrate(Verteidiger, VX, VY)) * ((Verteidiger.Leben - DefLeben) / 100)
            Angreifer.VirtuellesLeben = ATKLeben
            Verteidiger.VirtuellesLeben = DefLeben
            Return New Integer() {-KVerteidiger * BesetzungsBonus, -1}
        Else
            Dim GegenSchaden() As Single = Objektverwalter.Schadensberechnung(Verteidiger, VX, VY, AX, AY, DefLeben, ATKLeben, True, Verteidiger.GetSpieler.GetGlückPech(VX, VY).X * Glücksfaktor, Angreifer)
            If ATKLeben < 0 Then ATKLeben = 0
            Dim KVerteidiger As Integer = (Verteidiger.Kosten * Verteidiger.GetSpieler.Teurungsrate(Verteidiger, VX, VY)) * ((Verteidiger.Leben - DefLeben) / 100)
            Dim KAngreifer As Integer = (Angreifer.Kosten * Angreifer.GetSpieler.Teurungsrate(Angreifer, AX, AY)) * ((Angreifer.Leben - ATKLeben) / 100)
            Angreifer.VirtuellesLeben = ATKLeben
            Verteidiger.VirtuellesLeben = DefLeben
            Return New Integer() {KAngreifer - KVerteidiger * BesetzungsBonus, -1}
        End If
    End Function
    Public Function calculateBesetzungsbonus(ByVal Besetzer As ObjektEinheit, ByVal DefNeuLeben As Integer) As Single
        Dim Wert As Single = 1
        Dim G As ObjektGebäude = Objektverwalter.Spielfeld.Landschaften(Besetzer.X, Besetzer.Y, Besetzer.GetMap).Gebäude
        If G Is Nothing Then Return 1
        If G.GetSpieler.Team = Besetzer.GetSpieler.Team Then Return 1
        If Not Besetzer.KannBesetzen Then Return 1
        Dim RestP As Integer = G.Besetzung
        Dim L1 As Integer = Besetzer.getKP
        Dim L2 As Integer = getKP(DefNeuLeben)
        Dim R1 As Integer = Math.Round(RestP / L1, System.MidpointRounding.AwayFromZero)
        If L2 <= 0 Then
            If R1 > 0 Then
                Wert = 1 + (21 - R1) / R1
            Else
                Wert = 22
            End If
        Else
            Dim R2 As Integer = Math.Round(RestP / L2, System.MidpointRounding.AwayFromZero)
            If R1 < R2 Then Return 0.8
            If R1 = R2 And R1 < 2 Then Return 1
            Wert = 1 + (R2 - R1) / R1
        End If
        If Wert > 6 Then
            Return Wert / 2 + 3
        Else
            Return Wert
        End If
    End Function
#End Region
#Region "Nahkampfziehen"
    ''' <summary>
    ''' So werden die Einheiten  von einfachen KI's zum Ziel geführt
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub NahkampfZiehen()
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                Dim E As ObjektEinheit = Einheiten(MomentaneEinheit)
                If E.IsUsingUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) = True Then
                    If E.MinimaleReichweite = 1 Or Not Einheiten(MomentaneEinheit).Waffe1 = "Keine" Then
                        If E.KannBesetzen = False Then
                            'So das ist vieleicht eine Nahkampfeinheit und zwar kein Infaterist
                            'und diese Einheit kann nicht Angreifen oder doch nah ja das ist ja eine doofe KI
                            'Also keine Abfrage!
                            Dim WSS As New Wegsuchsystem(E, E.X, E.Y, E.GetMap, -1)
                            Dim Ziel As Point = GetNähestenNahkampfFeind(E, WSS)

                            If Ziel.X >= 0 Then
                                Dim Opfer As New Point(-1, -1)
                                Ziel = CalculateRealZiel(WSS, Ziel, E, Opfer)
                                If Opfer.X < 0 Then
                                    'Flucht nach vorne was?
                                    If E.KannTarnen Then
                                        If E.GetTarnung() Then
                                            Einheitauswählen(E, Ziel, KIModiExtern.Auftauchen, Nothing, WSS, 4)
                                            CalculatePotentiellenGegenschaden(E, Ziel, True)
                                            EinheitGezogenVonVorneStarten()
                                            Exit Sub
                                        Else
                                            Einheitauswählen(E, Ziel, KIModiExtern.Tarnen, Nothing, WSS, 4)
                                            CalculatePotentiellenGegenschaden(E, Ziel, True)
                                            EinheitGezogenVonVorneStarten()
                                            Exit Sub
                                        End If
                                    Else
                                        Einheitauswählen(E, Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                                        CalculatePotentiellenGegenschaden(E, Ziel, True)
                                        EinheitGezogenVonVorneStarten()
                                        Exit Sub
                                    End If
                                Else
                                    'Muhaha! Selbstmord überrascht? Wir denken an alles! Okay fast alles! Obwohl naja!
                                    Einheitauswählen(E, Ziel, KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Opfer.X, Opfer.Y, Schlachtfeld), WSS, 4)
                                    CalculatePotentiellenGegenschaden(E, Ziel, True)
                                    EinheitGezogenVonVorneStarten()
                                    Exit Sub
                                End If
                            Else
                                Ziel = ZumNähestenHQZiehen(Einheiten(MomentaneEinheit), WSS)
                                If Ziel.X > 0 Then
                                    Einheitauswählen(Einheiten(MomentaneEinheit), Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                                    CalculatePotentiellenGegenschaden(Einheiten(MomentaneEinheit), Ziel, True)
                                    EinheitGezogenVonVorneStarten()
                                    Exit Sub
                                End If
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        KIModusIntern = KIModiIntern.Infanterieziehen
    End Sub
    Protected Overrides Function CalculateRealZiel(ByRef WSS As Wegsuchsystem, ByVal Ziel As Point, ByVal Einheit As ObjektEinheit, ByRef Opfer As Point) As Point
        Opfer = New Point(-1, -1)
        Dim urspvl As Single = WSS.Einheit.VirtuellesLeben
        Dim Z As Point = Ziel
        WSS.Ziel(Ziel.X, Ziel.Y, True)
        Dim WegPunktIndex As Integer = -1
        For I = 0 To WSS.WegpunkteX.Length - 1
            If WSS.getRundeDiskret(WSS.getBewegungspunktekosten(I), False) = 0 Then
                Dim GegSchaden As Integer = CalculatePotentiellenGegenschaden(WSS.Einheit, New Point(WSS.WegpunkteX(I), WSS.WegpunkteY(I)), False)
                WSS.Einheit.VirtuellesLeben = urspvl
                If GegSchaden < (Spieler.Teurungsrate(WSS.Einheit, WSS.WegpunkteX(I), WSS.WegpunkteY(I)) * WSS.Einheit.Kosten * Einheit.Leben / 100) * MaximalerSchadensSatz Then
                    WegPunktIndex = I
                    Exit For
                End If
            End If
        Next

        If WegPunktIndex < 0 Then
            'Wir müssen fliehen!
            Dim BestVerlust As Integer
            Dim BestFeld As New Point(-1, -1)
            Dim Distance As Integer
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    If WSS.getRundeDiskret(WSS.getBewegungspunktekosten(X, Y), False) = 0 Then
                        'Wir können dieses Feld jetzt zum Fliehen in betracht ziehen.
                        Dim aktuellerVerlust As Integer = 0
                        If aktuellerVerlust > 0 Then aktuellerVerlust = 0
                        aktuellerVerlust *= Gegenschaden
                        aktuellerVerlust += CalculatePotentiellenGegenschaden(WSS.Einheit, New Point(X, Y), False)
                        WSS.Einheit.VirtuellesLeben = urspvl
                        If BestFeld.X = -1 Then
                            'Dann halt das erst-beste
                            BestFeld = New Point(X, Y)
                            BestVerlust = aktuellerVerlust
                            Distance = Einheit.GetDistance(Ziel)
                        Else
                            Dim D As Integer = Einheit.GetDistance(Ziel)
                            If aktuellerVerlust < BestVerlust Then
                                BestFeld = New Point(X, Y)
                                BestVerlust = aktuellerVerlust
                                Distance = D
                            ElseIf aktuellerVerlust = BestVerlust And D < Distance Then
                                BestFeld = New Point(X, Y)
                                BestVerlust = aktuellerVerlust
                                Distance = D
                            End If
                        End If
                    End If
                Next
            Next
            If BestFeld.X >= 0 Then
                Z = BestFeld
            End If
        Else
            Z = New Point(WSS.WegpunkteX(WegPunktIndex), WSS.WegpunkteY(WegPunktIndex))
        End If
        Opfer = GetBonusOpfer(Einheit, Z.X, Z.Y)
        Return Z
    End Function
    ''' <summary>
    ''' Diese Funktion beweist das die Programmierer dieses Spiels Humor hatten!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function GetBonusOpfer(ByVal Angreifer As ObjektEinheit, ByVal X As Integer, ByVal Y As Integer) As Point
        Dim BonusOpfer As New Point(-1, -1)
        Dim MeistSchaden As Integer

        'Wir könnten mal Angreifer!
        For Each Unit In Objektverwalter.Spielfeld.Einheiten
            If Unit IsNot Nothing Then
                If Unit.GetSpieler.Team <> Angreifer.GetSpieler.Team Then
                    If Unit.isSichtbar(Angreifer.GetSpieler.Team) Then
                        If Angreifer.IsAttackable(Unit, True, False) Then
                            If Angreifer.CanAttackFromField(X, Y, Unit.X, Unit.Y) Then
                                Dim aktuellenSchaden As Integer = GegnerVerluste(Angreifer, X, Y, Unit, Unit.X, Unit.Y)
                                If aktuellenSchaden > 0 Then
                                    'schonmal generell gut.
                                    If BonusOpfer.X < 0 Then
                                        MeistSchaden = aktuellenSchaden
                                        BonusOpfer = New Point(Unit.X, Unit.Y)
                                    Else
                                        If aktuellenSchaden > MeistSchaden Then
                                            MeistSchaden = aktuellenSchaden
                                            BonusOpfer = New Point(Unit.X, Unit.Y)
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        Next
        Return BonusOpfer
    End Function
    ''' <summary>
    ''' Doppelter Angriff UV!
    ''' </summary>
    ''' <param name="Angreifer"></param>
    ''' <param name="AX"></param>
    ''' <param name="AY"></param>
    ''' <param name="Verteidiger"></param>
    ''' <param name="VX"></param>
    ''' <param name="VY"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GegnerVerluste(ByVal Angreifer As ObjektEinheit, ByVal AX As Integer, ByVal AY As Integer, ByVal Verteidiger As ObjektEinheit, ByVal VX As Integer, ByVal VY As Integer) As Integer
        Dim ATKLeben As Single = Angreifer.Leben
        Dim DefLeben As Single = Verteidiger.Leben
        Dim VerursachterSchaden() As Single = Objektverwalter.Schadensberechnung(Angreifer, AX, AY, VX, VY, ATKLeben, DefLeben, True, Angreifer.GetSpieler.GetGlückPech(AX, AY).X * Glücksfaktor, Verteidiger)
        If DefLeben < 0 Then DefLeben = 0



        Dim KVerteidiger As Integer = (Verteidiger.Kosten * Verteidiger.GetSpieler.Teurungsrate(Verteidiger, VX, VY)) * ((Verteidiger.Leben - DefLeben) / 100)

        Return KVerteidiger
    End Function
#End Region
#Region "Infi Attack"
    ''' <summary>
    ''' So ziehen die Infanteristen
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub InfanterieZiehen()
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                If Einheiten(MomentaneEinheit).IsUsingUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) = True Then
                    If Einheiten(MomentaneEinheit).KannBesetzen Then
                        Dim WSS As Wegsuchsystem = Nothing
                        Dim Ziel1 As Point2 = GetBestesNahkampfOpferFeldSicher(Einheiten(MomentaneEinheit), WSS, GetAllNahKampffelder(Einheiten(MomentaneEinheit), True, WSS))
                        'Können wir angreifen?
                        If Ziel1.Point1.X >= 0 And Ziel1.Point2.X >= 0 Then
                            Einheitauswählen(Einheiten(MomentaneEinheit), Ziel1.Point1, KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Ziel1.Point2.X, Ziel1.Point2.Y, Schlachtfeld), WSS, 4)
                            CalculatePotentiellenGegenschaden(Einheiten(MomentaneEinheit), Ziel1.Point1, True)
                            EinheitGezogenVonVorneStarten()
                            Exit Sub
                        Else
                            'wir schauen ob wir zu einer Besetzung gehen

                            If InfantrieMoveToTransporterOrBesetzung(Einheiten(MomentaneEinheit)) Then
                                Exit Sub
                            ElseIf Not Einheiten(MomentaneEinheit).Waffe1 = "Keine" Or Einheiten(MomentaneEinheit).MinimaleReichweite = 1 Then
                                Dim E As ObjektEinheit = Einheiten(MomentaneEinheit)
                                WSS = New Wegsuchsystem(E, , True)
                                'Wir gehen zu einem Feind.
                                Dim Ziel As Point = GetNähestenNahkampfFeind(E, WSS)
                                If Ziel.X >= 0 Then
                                    Dim Opfer As New Point(-1, -1)
                                    Ziel = CalculateRealZiel(WSS, Ziel, Einheiten(MomentaneEinheit), Opfer)
                                    If Opfer.X < 0 Then
                                        'Flucht nach vorne was?
                                        If E.KannTarnen Then
                                            If E.GetTarnung() Then
                                                Einheitauswählen(E, Ziel, KIModiExtern.Auftauchen, Nothing, WSS, 4)
                                                CalculatePotentiellenGegenschaden(E, Ziel, True)
                                                EinheitGezogenVonVorneStarten()
                                                Exit Sub
                                            Else
                                                Einheitauswählen(E, Ziel, KIModiExtern.Tarnen, Nothing, WSS, 4)
                                                CalculatePotentiellenGegenschaden(E, Ziel, True)
                                                EinheitGezogenVonVorneStarten()
                                                Exit Sub
                                            End If
                                        Else
                                            Einheitauswählen(E, Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                                            CalculatePotentiellenGegenschaden(E, Ziel, True)
                                            EinheitGezogenVonVorneStarten()
                                            Exit Sub
                                        End If
                                    Else
                                        'Muhaha! Selbstmord überrascht? Wir denken an alles! Okay fast alles! Obwohl naja!
                                        Einheitauswählen(E, Ziel, KIModiExtern.Angriff, Objektverwalter.Spielfeld.Einheiten(Opfer.X, Opfer.Y, Schlachtfeld), WSS, 4)
                                        CalculatePotentiellenGegenschaden(E, Ziel, True)
                                        EinheitGezogenVonVorneStarten()
                                        Exit Sub
                                    End If
                                Else
                                    Ziel = ZumNähestenHQZiehen(Einheiten(MomentaneEinheit), WSS)
                                    If Ziel.X > 0 Then
                                        Einheitauswählen(Einheiten(MomentaneEinheit), Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                                        CalculatePotentiellenGegenschaden(Einheiten(MomentaneEinheit), Ziel, True)
                                        EinheitGezogenVonVorneStarten()
                                        Exit Sub
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        KIModusIntern = KIModiIntern.Fernkampfziehen
    End Sub
#End Region
#Region "Move Indirects"
    ''' <summary>
    ''' So werden die Fernkampf Einheiten der Kinderleichten KI gezogen
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub Fernkampfziehen()
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                If Einheiten(MomentaneEinheit).IsUsingUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) = True Then
                    If Einheiten(MomentaneEinheit).MaximaleReichweite > 1 Then
                        If Einheiten(MomentaneEinheit).KannBesetzen = False Then
                            If MoveIndirect(Einheiten(MomentaneEinheit)) Then
                                Exit Sub
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        KIModusIntern = KIModiIntern.Rückzug
    End Sub
    ''' <summary>
    ''' Let's move our Indirect Unit to a save and effectiv place.
    ''' </summary>
    ''' <param name="Einheit"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function MoveIndirect(ByVal Einheit As ObjektEinheit) As Boolean
        Dim WSS As New Wegsuchsystem(Einheit, Einheit.X, Einheit.Y, Einheit.GetMap, -1)
        Dim Ziel As Point = GetNähestesFernkampffeldSicher(Einheit, WSS)
        If Ziel.X >= 0 Then
            Einheitauswählen(Einheit, Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
            CalculatePotentiellenGegenschaden(Einheit, Ziel, True)
            EinheitGezogenVonVorneStarten()
            Return True
        Else
            Ziel = ZumNähestenHQZiehen(Einheit, WSS)
            If Ziel.X > 0 Then
                Einheitauswählen(Einheit, Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                CalculatePotentiellenGegenschaden(Einheit, Ziel, True)
                EinheitGezogenVonVorneStarten()
                Return True
            End If
        End If
        Return False
    End Function
    Function GetNähestesFernkampffeldSicher(ByVal E As ObjektEinheit, ByRef WSS As Wegsuchsystem) As Point
        Dim Ziel As New Point(-1, -1)
        Dim MomentaneWegkosten As Integer = -1
        If E.MaximaleReichweite > 1 Then
            If WSS Is Nothing Then
                WSS = New Wegsuchsystem(E, E.X, E.Y, E.GetMap, -1)
            End If
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe
                    If WSS.getBewegungspunktekosten(X, Y) >= 0 Then
                        If IsFeldLeer(X, Y, E) = True Then
                            'Wir können das Feld erreichen
                            If KannFernkampfGemachtWerden(E, X, Y) = True Then
                                If WSS.getBewegungspunktekosten(X, Y) < MomentaneWegkosten Then
                                    MomentaneWegkosten = WSS.getBewegungspunktekosten(X, Y)
                                    Ziel = New Point(X, Y)
                                ElseIf WSS.getBewegungspunktekosten(X, Y) = MomentaneWegkosten And Zufallszahl(0, 1) = 1 Then
                                    MomentaneWegkosten = WSS.getBewegungspunktekosten(X, Y)
                                    Ziel = New Point(X, Y)
                                ElseIf MomentaneWegkosten = -1 Then
                                    MomentaneWegkosten = WSS.getBewegungspunktekosten(X, Y)
                                    Ziel = New Point(X, Y)
                                End If
                            End If
                        End If
                    End If
                Next
            Next
        End If
        Ziel = CalculateRealZiel(WSS, Ziel, E, New Point(-1, -1))
        Return Ziel
    End Function
#End Region
#Region "Go Back and Give Ration"
    Private Sub Rückzug()
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                Dim E As ObjektEinheit = Einheiten(MomentaneEinheit)
                If E.HatsichBewegt = False Then
                    If E.Treibstoff <> 0 Then
                        If E.IsLowPowerUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) Then
                            Dim WSS As New Wegsuchsystem(E, E.X, E.Y, E.GetMap, -1)
                            Dim Ziel As Point = GetNähestesRationsFeld(E, WSS)
                            If Ziel.X >= 0 Then
                                Einheitauswählen(Einheiten(MomentaneEinheit), Ziel, KIModiExtern.Warten, Nothing, WSS, 4)
                                CalculatePotentiellenGegenschaden(Einheiten(MomentaneEinheit), Ziel, True)
                                EinheitGezogenVonVorneStarten()
                                If E.getKP < MinimaleKP Then
                                    If Ziel.X = E.X And E.Y = Ziel.Y Then
                                        'Nun warten wir bis wir geheilt sind.
                                        Spieler.AddExternGezogeneEinheit(E.X, E.Y, E, ObjektSpieler.ExternGezogeneEinheit.Befehle.Heilen, "", ObjektSpieler.ExternGezogeneEinheit.NächsteBefehle.Entfernen)
                                    End If
                                End If
                                Exit Sub
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        MomentaneEinheit = 0
        KIModusIntern = KIModiIntern.Ration
    End Sub
    Private Sub Ration()
        While MomentaneEinheit < Einheiten.Length
            If ExistUnit(Einheiten(MomentaneEinheit)) = True Then
                Dim E As ObjektEinheit = Einheiten(MomentaneEinheit)
                If E.Fähigkeit = "Ration" Then
                    If E.IsUsingUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) Then
                        If Not E.HasLadung Then
                            Dim WSS As New Wegsuchsystem(E, E.X, E.Y, E.GetMap, -1)
                            Dim Ziel As Point = GetNähestesRationsVerteilFeld(E, WSS)
                            If Ziel.X >= 0 Then
                                Einheitauswählen(Einheiten(MomentaneEinheit), Ziel, KIModiExtern.Ration, Nothing, WSS, 4)
                                CalculatePotentiellenGegenschaden(Einheiten(MomentaneEinheit), Ziel, True)
                                EinheitGezogenVonVorneStarten()
                                Exit Sub
                            End If
                        End If
                    End If
                End If
            End If
            MomentaneEinheit += 1
        End While
        MomentaneEinheit = 0
        KIModusIntern = KIModiIntern.TransporterVerladen
    End Sub

#End Region
#Region "Bauen"
    ''' <summary>
    ''' Jetzt werden Truppen gebaut!
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub Bauen()
        TrimGebäude()
        'Die Gebäude nach der Distanz zum Gegner sortieren.
        Gebäude = SortGebäude(Gebäude, GebäudeSortierKriterien.NähestenZumFeind)
        If Spieler.Bauprioritäten IsNot Nothing Then
            KIGenerellerSuperBau.Bauen(Gebäude, Spieler.Bauprioritäten)
        Else
            'Den Bau initialisieren....
            'Gebäude feindlichen
            Dim EnemyBuildings As Integer = CountEnemyBuildings()
            Dim NeutralBuildings As Integer = CountNeutralBuildings()
            'Eigene Gebäude
            Dim OwnBases As Integer = CountOwnBases()
            Dim OwnAirports As Integer = CountOwnAirports()
            Dim OwnPorts As Integer = CountOwnPorts()
            'Einheiten Feindliche
            Dim EnemyAirUnits As Integer = CountEnemyAirUnits()
            Dim IndirectEnemyUnits As Integer = CountIndirectEnemys()
            Dim DirectEnemyUnits As Integer = CountDirectEnemys()
            Dim EnemyGroundUnits As Integer = CountEnemyGroundUnits()
            Dim EnemySeaForce As Integer = CountEnemySeaUnits()
            Dim EnemyUnits As Integer = CountEnemyUnits()
            Dim EnemyCopters As Integer = CountEnemyCopters()
            Dim EnemyAntiAirUnits As Integer = CountEnemyAntiAirUnits()
            'Einheiten Eigene
            Dim AntiAirUnits As Integer = CountAntiAirUnits()
            Dim OwnGroundUnits As Integer = CountGroundUnits()
            Dim Infis As Integer = CountInfanteristen()
            Dim OwnUnits As Integer = CountOwnUnits()
            Dim OwnLanders As Integer = CountAnyUnit("L-BOOT")
            Dim OwnTransportplanes As Integer = CountAnyUnit("T-FLUGZEUG")
            Dim OwnTTPs As Integer = CountAnyUnit("TTP")
            Dim OwnTHelis As Integer = CountAnyUnit("T-HELI")
            'Noch andere Sachen
            Dim LBootBau As Boolean = IsLandeBootBauSinnvoll() 'Landeboote
            Dim BauModus As Integer = 0
            'Wenn das False wird dann schauen wir weiter und weiter und weiter.=D
            Dim NichtsGebaut As Boolean = True
            Dim Income As Integer = Spieler.Einkommen
            Dim FondsNächsteRunde As Integer = Spieler.Fonds
            FondsNächsteRunde += Income - Spieler.GetRepairCosts
            Dim AusgabeFonds As Integer = 0
            Dim TeuersteEinheitNächsteRunde As Integer = GetExpensivestUnitCosts(FondsNächsteRunde)
            If Objektverwalter.Spielfeld.Runde > 1 Then
                If NächsteRundeGeld < Spieler.Fonds Then
                    AusgabeFonds = Spieler.Fonds 'Wir dürfen alles ausgeben. Hähä!
                Else
                    If Income <= MinimalesEinkommen Then
                        AusgabeFonds = Spieler.Fonds 'Wir dürfen alles ausgeben. Hähä!
                    Else
                        'da muss mir wohl etwas Sparsamer sein!
                        AusgabeFonds = FondsNächsteRunde - TeuersteEinheitNächsteRunde
                    End If
                End If
            Else
                AusgabeFonds = Spieler.Fonds
            End If


            'Jetzt sollten wir nur noch Baugebäude haben!
            If Spieler.VeränderteWerte.KeinBau = False Then
                'wir können Truppen bauen.
                While MomentaneEinheit < Gebäude.Length
Start:
                    If InfiBau(Infis, NeutralBuildings, EnemyBuildings, OwnBases, AntiAirUnits, EnemyAirUnits) And BauModus <= 0 Then
                        If Infis > 0 And Objektverwalter.Spielfeld.Runde > 2 And AusgabeFonds > MinimaleFonds Then
                            'Das ist jetzt ne blöde Situation Nicht!
                            'Bauen wir Panzer oder Infis??????? Keinen Plan
                            If Zufallszahl(1, 100) <= 50 Or AusgabeFonds > NächsteRundeGeld * 2 Then
                                Dim Ausgabe As Integer = ProduceBestUnit(EnemyAntiAirUnits, EnemyAirUnits, EnemySeaForce, EnemyGroundUnits, DirectEnemyUnits, IndirectEnemyUnits, OwnBases, OwnAirports, OwnPorts, OwnLanders, OwnGroundUnits, Infis, AusgabeFonds)
                                AusgabeFonds -= Ausgabe
                                If Ausgabe > 0 Then
                                    NichtsGebaut = False
                                End If
                            Else
                                Dim Ausgabe As Integer = InfisBauen(AusgabeFonds)
                                AusgabeFonds -= Ausgabe
                                If Ausgabe > 0 Then
                                    Infis += 1
                                    NichtsGebaut = False
                                End If
                            End If
                        Else
                            Dim Ausgabe As Integer = InfisBauen(AusgabeFonds)
                            AusgabeFonds -= Ausgabe
                            If Ausgabe > 0 Then
                                Infis += 1
                                NichtsGebaut = False
                            End If
                        End If
                        If NichtsGebaut Then
                            BauModus = 1
                            GoTo Start
                        End If
                    ElseIf AntiAirBau(AntiAirUnits, EnemyAirUnits) And BauModus <= 1 Then
                        'Sehr heikel jetzt brauchen wir wohl ein bisschen Anti-Air Was? Also Jäger,Flak,
                        If AntiAirUnits - 2 <= EnemyCopters And AntiAirUnits > 3 Then
                            'Hey! Wir könnten auch Copter bauen oder?
                            If Zufallszahl(0, 2) = 0 Then
                                'Bauen wir halt einen Copter!
                                Dim Ausgabe As Integer = ProduceCopter(AusgabeFonds)
                                AusgabeFonds -= Ausgabe
                                If Ausgabe > 0 Then
                                    AntiAirUnits += 1
                                    NichtsGebaut = False
                                End If
                            Else
                                Dim Ausgabe As Integer = ProduceAntiAir(AusgabeFonds)
                                AusgabeFonds -= Ausgabe
                                If Ausgabe > 0 Then
                                    AntiAirUnits += 1
                                    NichtsGebaut = False
                                End If
                            End If
                        Else
                            'Anti-Air auf geht's
                            Dim Ausgabe As Integer = ProduceAntiAir(AusgabeFonds)
                            AusgabeFonds -= Ausgabe
                            If Ausgabe > 0 Then
                                AntiAirUnits += 1
                                NichtsGebaut = False
                            End If
                        End If
                        If NichtsGebaut Then
                            BauModus = 2
                            GoTo Start
                        End If
                        'So Transporter Abfrage!
                        'Zuerst mal Infi Transport!!!
                    ElseIf InfiTransportBau(OwnAirports, OwnTransportplanes, Infis, NeutralBuildings, EnemyBuildings, OwnBases, OwnTTPs, OwnTHelis, AntiAirUnits, EnemyAirUnits) And BauModus <= 2 Then
                        If OwnTTPs = 0 And Spieler.CanProduceUnit("TTP") Then
                            Dim Ausgabe As Integer = ProduceUnit("TTP", AusgabeFonds)
                            AusgabeFonds -= Ausgabe
                            If Ausgabe > 0 Then
                                OwnTTPs += 1
                                NichtsGebaut = False
                            End If
                        ElseIf OwnTHelis = 0 And Spieler.CanProduceUnit("T-HELI") Then
                            Dim Ausgabe As Integer = ProduceUnit("T-HELI", AusgabeFonds)
                            AusgabeFonds -= Ausgabe
                            If Ausgabe > 0 Then
                                OwnTHelis += 1
                                NichtsGebaut = False
                            End If
                        ElseIf OwnTTPs = 1 And Einheiten.Length > 20 Then
                            Dim Ausgabe As Integer = ProduceUnit("TTP", AusgabeFonds)
                            AusgabeFonds -= Ausgabe
                            If Ausgabe > 0 Then
                                OwnTTPs += 1
                                NichtsGebaut = False
                            End If
                        ElseIf OwnTHelis = 1 And Einheiten.Length > 20 Then
                            Dim Ausgabe As Integer = ProduceUnit("T-HELI", AusgabeFonds)
                            AusgabeFonds -= Ausgabe
                            If Ausgabe > 0 Then
                                OwnTHelis += 1
                                NichtsGebaut = False
                            End If
                        End If
                        If NichtsGebaut Then
                            BauModus = 3
                            GoTo Start
                        End If
                        'T-Flugzeuge oder Landeboote
                    ElseIf LuftTransportBau(OwnAirports, OwnTransportplanes) And BauModus <= 3 Then
                        Dim Ausgabe As Integer = ProduceUnit("T-FLUGZEUG", AusgabeFonds)
                        AusgabeFonds -= Ausgabe
                        If Ausgabe > 0 Then
                            OwnTransportplanes += 1
                            NichtsGebaut = False
                        End If
                        If NichtsGebaut Then
                            BauModus = 4
                            GoTo Start
                        End If
                    ElseIf LBootBau And OwnLanders / OwnUnits * 100 < 10 And BauModus <= 4 Then
                        Dim Ausgabe As Integer = ProduceUnit("L-BOOT", AusgabeFonds)
                        AusgabeFonds -= Ausgabe
                        If Ausgabe > 0 Then
                            OwnTransportplanes += 1
                            NichtsGebaut = False
                        End If
                        If NichtsGebaut Then
                            BauModus = 5
                            GoTo Start
                        End If
                    Else
                        Dim Ausgabe As Integer = ProduceBestUnit(EnemyAntiAirUnits, EnemyAirUnits, EnemySeaForce, EnemyGroundUnits, DirectEnemyUnits, IndirectEnemyUnits, OwnBases, OwnAirports, OwnPorts, OwnLanders, OwnGroundUnits, Infis, AusgabeFonds)
                        AusgabeFonds -= Ausgabe
                        If Ausgabe > 0 Then
                            NichtsGebaut = False
                        End If
                    End If

                    If NichtsGebaut Then
                        MomentaneEinheit = Gebäude.Length + 1 'Damit wären wir dann wohl fertig
                    Else
                        BauModus = 0
                        'Weiter Geht es!
                        NichtsGebaut = True
                        MomentaneEinheit = 0
                    End If
                End While
            End If
        End If
        'Bau beenden!
        MomentaneEinheit = 0
        If Schlachtfeld = ObjektSpielfeld.Bodenschlacht And Objektverwalter.Spielfeld.Regeln.Luftschlacht = True Then
            Schlachtwechsel(EinheitenSortierKriterien.Zufall)
            KIModusIntern = KIModiIntern.StartWarten
        Else
            'Wir beenden.
            KIModusIntern = KIModiIntern.RundenEndeGabeEinsetzen
        End If
    End Sub

#Region "Buildfunctions simply a new Region"
    ''' <summary>
    ''' Baut einen Infi Mech oder Scharfschützen irgendetwas, das besetzen kann.;)
    ''' </summary>
    ''' <remarks></remarks>
    Private Function InfisBauen(Optional ByRef Prüffonds As Integer = -1) As Integer
        Dim Ausgabe As Integer = 0
        If Prüffonds < 0 Then
            Prüffonds = Spieler.Fonds
        End If
        For I = 0 To Gebäude.Length - 1
            If IsFeldLeer(Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y) Then
                Dim Infis As String() = GetBuildInfis(Gebäude(I), Prüffonds)
                If Infis.Length > 0 Then
                    If CanMoveAfterBuilding(New EinheitInfanterie(0, 0, 0), Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y) = True Then
                        If Objektverwalter.Spielfeld.Runde <= 2 Or Zufallszahl(1, 100) < 70 Then
                            Dim BilligsteTruppe As ObjektEinheit = Nothing
                            For I2 = 0 To Infis.Length - 1
                                Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(Infis(I2), Spieler.Spieler, Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y)
                                If BilligsteTruppe Is Nothing Then
                                    BilligsteTruppe = E
                                ElseIf E.Kosten < BilligsteTruppe.Kosten Then
                                    BilligsteTruppe = E
                                ElseIf E.Kosten = BilligsteTruppe.Kosten And Zufallszahl(0, 2) = 0 Then
                                    BilligsteTruppe = E
                                End If
                            Next
                            'Dann mal los ihr Infis
                            Ausgabe = BilligsteTruppe.Kosten * Spieler.Teurungsrate(BilligsteTruppe, BilligsteTruppe.X, BilligsteTruppe.Y)
                            GebäudeAuswählen(KIModiExtern.EinheitBauen, Gebäude(I), BilligsteTruppe)
                            Return Ausgabe
                        Else
                            Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(Infis(Zufallszahl(0, Infis.Length - 1)), Spieler.Spieler, Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y)
                            Ausgabe = E.Kosten * Spieler.Teurungsrate(E, E.X, E.Y)
                            GebäudeAuswählen(KIModiExtern.EinheitBauen, Gebäude(I), E)
                            Return Ausgabe
                        End If
                    End If
                End If
            End If
        Next
        Return Ausgabe
    End Function
    ''' <summary>
    ''' Stellt eine Anti-Air-Unit her.
    ''' </summary>
    ''' <param name="Prüffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ProduceAntiAir(ByVal Prüffonds As Integer) As Integer
        Dim Ausgabe As Integer = 0
        If Prüffonds < 0 Then
            Prüffonds = Spieler.Fonds
        End If
        Dim NähesteGebäude As ObjektGebäude = Nothing
        Dim Näheste As Integer = -1
        For I = 0 To Gebäude.Length - 1
            If IsFeldLeer(Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y) Then 'Wir wollen ja was bauen!
                If CanProduceAntiAir(Gebäude(I), Prüffonds) Then
                    Dim E As Integer = GetAirDistance(Gebäude(I))
                    If Näheste < 0 Then
                        Näheste = E
                        NähesteGebäude = Gebäude(I)
                    ElseIf Näheste > E Then
                        Näheste = E
                        NähesteGebäude = Gebäude(I)
                    ElseIf Näheste = E And Zufallszahl(0, 2) = 0 Then
                        Näheste = E
                        NähesteGebäude = Gebäude(I)
                    End If
                End If
            End If
        Next
        If Not NähesteGebäude Is Nothing Then
            'Das Gebäude baut jetzt eine Anti-Air-Einheit
            Dim AntiAir As ObjektEinheit() = NähesteGebäude.GetProduceableAntiAirUnits(Prüffonds)
            Dim Beste As Integer = -1
            Dim Stärke As Integer = -1
            For I = 0 To AntiAir.Length - 1
                If CanMoveAfterBuilding(AntiAir(I), AntiAir(I).X, AntiAir(I).Y) Then
                    If AntiAir(I).MinimaleReichweite > 1 And Näheste <= LuftwaffenAbstand Then
                        'Jetzt eine Fernwaffe wäre sehr schlecht
                    Else
                        Dim NeuStärke As Integer = KIGenerellerSuperBau.GetAntiAirDamage(AntiAir(I)) / (AntiAir(I).Kosten * Spieler.Teurungsrate(AntiAir(I), AntiAir(I).X, AntiAir(I).Y))
                        If NeuStärke > Stärke Then
                            Stärke = NeuStärke
                            Beste = I
                        ElseIf NeuStärke = Stärke And Zufallszahl(0, 2) = 0 Then
                            Stärke = NeuStärke
                            Beste = I
                        End If
                    End If
                End If
            Next
            If Beste >= 0 Then
                'Gut wir bauen eine Anti-Luft-Einheit
                Ausgabe = AntiAir(Beste).Kosten * Spieler.Teurungsrate(AntiAir(Beste), AntiAir(Beste).X, AntiAir(Beste).Y)
                GebäudeAuswählen(KIModiExtern.EinheitBauen, NähesteGebäude, AntiAir(Beste))
                Return Ausgabe
            End If
        End If
        Return Ausgabe
    End Function
    ''' <summary>
    ''' Stellt einen K-Heli her oder so!
    ''' Halt ein Heli mit Wumms!
    ''' </summary>
    ''' <param name="Prüffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ProduceCopter(ByVal Prüffonds As Integer) As Integer
        Dim Ausgabe As Integer = 0
        If Prüffonds < 0 Then
            Prüffonds = Spieler.Fonds
        End If
        For I = 0 To Gebäude.Length - 1
            If IsFeldLeer(Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y) Then 'Wir wollen ja was bauen!
                If CanProduceAttackCopters(Gebäude(I), Prüffonds) Then
                    Dim BListe As String() = Gebäude(I).GetBauliste(Gebäude(I).Spieler)
                    Dim TeuersterHeli As ObjektEinheit = Nothing
                    For I2 = 0 To BListe.Length - 1
                        Dim Copter As ObjektEinheit = ObjektLadeklasse.NewEinheit(BListe(I2), Spieler.Spieler, Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y)
                        If Gebäude(I).CanBuildUnit(Copter, Prüffonds) Then
                            If CanMoveAfterBuilding(Copter, Copter.X, Copter.Y) Then
                                If Copter.Bewegungsart = MovementSorts.Helikopter.ToString Then
                                    If Not Copter.HasNoWeapons Then
                                        If Gebäude(I).CanBuildUnit(Copter, Prüffonds) Then
                                            If TeuersterHeli Is Nothing Then
                                                TeuersterHeli = Copter
                                            ElseIf TeuersterHeli.Kosten < Copter.Kosten Then
                                                TeuersterHeli = Copter
                                            ElseIf TeuersterHeli.Kosten = Copter.Kosten And Zufallszahl(0, 2) = 0 Then
                                                TeuersterHeli = Copter
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    Next
                    If Not TeuersterHeli Is Nothing Then
                        Ausgabe = TeuersterHeli.Kosten * Spieler.Teurungsrate(TeuersterHeli, TeuersterHeli.X, TeuersterHeli.Y)
                        GebäudeAuswählen(KIModiExtern.EinheitBauen, Gebäude(I), TeuersterHeli)
                        Return Ausgabe
                    End If
                End If
            End If
        Next
        Return Ausgabe
    End Function
    ''' <summary>
    ''' Stellt eine ganz bestimmte Einheit her.
    ''' </summary>
    ''' <param name="Unit"></param>
    ''' <param name="Prüffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ProduceUnit(ByVal Unit As String, ByVal Prüffonds As Integer) As Integer
        Dim Ausgabe As Integer = 0
        If Prüffonds < 0 Then
            Prüffonds = Spieler.Fonds
        End If
        For I = 0 To Gebäude.Length - 1
            If IsFeldLeer(Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y) Then 'Wir wollen ja was bauen!
                If Gebäude(I).CanBuildUnit(Unit, Prüffonds) Then
                    Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(Unit, Spieler.Spieler, Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y)
                    If CanMoveAfterBuilding(E, E.X, E.Y) Then
                        Ausgabe = E.Kosten * Spieler.Teurungsrate(E, E.X, E.Y)
                        GebäudeAuswählen(KIModiExtern.EinheitBauen, Gebäude(I), E)
                        Return Ausgabe
                    End If
                End If
            End If
        Next
        Return Ausgabe
    End Function
    ''' <summary>
    ''' Stellt die beste Einheit her.
    ''' </summary>
    ''' <param name="SeaUnits"></param>
    ''' <param name="GroundUnits"></param>
    ''' <param name="DirectUnits"></param>
    ''' <param name="IndirectUnits"></param>
    ''' <param name="Prüffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ProduceBestUnit(ByVal AntiAirUnits As Integer, ByVal AirUnits As Integer, ByVal SeaUnits As Integer, ByVal GroundUnits As Integer, ByVal DirectUnits As Integer, ByVal IndirectUnits As Integer, ByVal OwnBases As Integer, ByVal OwnAirports As Integer, ByVal OwnHarbours As Integer, ByVal OwnLanders As Integer, ByVal OwnGroundUnits As Integer, ByVal OwnInfis As Integer, ByVal Prüffonds As Integer) As Integer
        Dim Ausgabe As Integer = 0
        Dim LuftwaffenBau As Boolean = True
        If AntiAirUnits / (OwnGroundUnits - OwnInfis) > 1 Then LuftwaffenBau = False 'Die Stürzt sonst nur ab!
        Dim KOStärke As KOStärke = GetKOStärke()
        Dim BauModus As Integer = 0
        Dim HeliOffensive As Integer = Spieler.KOS(0).GetOffensivStärke(New K_Heli(Spieler.Spieler, 0, 0))
        Dim HeliDeffensive As Integer = Spieler.KOS(0).GetDeffensivStärke(New K_Heli(Spieler.Spieler, 0, 0))
Start:
        Select Case KOStärke
            Case KIMittel.KOStärke.Luft
                'Auf zur Luft Waffe!
                If LuftwaffenBau And OwnAirports > 0 And BauModus <= 0 Or Zufallszahl(1, 100) >= 70 Then
                    Ausgabe = ProduceAirUnit(AirUnits, Prüffonds)
                    If Ausgabe = 0 Then
                        BauModus = 1
                        GoTo Start
                    End If
                ElseIf OwnBases > 0 And OwnLanders = 0 Then
                    Ausgabe = ProduceGroundUnit(Prüffonds)
                ElseIf OwnLanders > 0 And OwnHarbours > 0 And BauModus <= 1 Then
                    Ausgabe = ProduceSeaUnit(Prüffonds)
                    If Ausgabe = 0 Then
                        BauModus = 2
                        GoTo Start
                    End If
                Else
                    Ausgabe = ProduceGroundUnit(Prüffonds)
                End If
            Case KIMittel.KOStärke.Direkt
                If IndirectUnits / DirectUnits > 1.5# Or Zufallszahl(1, 100) >= 80 Then
                    Ausgabe = ProduceInDirectUnit(LuftwaffenBau, Prüffonds)
                Else
                    Ausgabe = ProduceDirectUnit(LuftwaffenBau, Prüffonds)
                End If
            Case KIMittel.KOStärke.Indirekt
                If Zufallszahl(1, 100) >= 70 Then
                    Ausgabe = InfisBauen(Prüffonds)
                    If Ausgabe = 0 Then
                        GoTo IndirekterWaffenBau
                    End If
                Else
IndirekterWaffenBau:
                    If DirectUnits / IndirectUnits > 1.5# Or Zufallszahl(1, 100) >= 80 Then
                        Ausgabe = ProduceInDirectUnit(LuftwaffenBau, Prüffonds)
                    Else
                        Ausgabe = ProduceDirectUnit(LuftwaffenBau, Prüffonds)
                    End If
                End If
            Case KIMittel.KOStärke.Boden
                If OwnLanders > 0 And OwnHarbours > 0 And Zufallszahl(1, 100) > 90 And BauModus <= 0 Then
                    Ausgabe = ProduceSeaUnit(Prüffonds)
                    If Ausgabe = 0 Then
                        BauModus = 1
                        GoTo Start
                    End If
                ElseIf LuftwaffenBau And OwnAirports > 0 And BauModus <= 1 And Zufallszahl(1, 100) > 90 Then
                    Ausgabe = ProduceAirUnit(AirUnits, Prüffonds)
                    If Ausgabe = 0 Then
                        BauModus = 2
                        GoTo Start
                    End If
                Else
                    Ausgabe = ProduceGroundUnit(Prüffonds)
                End If
            Case KIMittel.KOStärke.See
                If OwnHarbours > 0 And BauModus <= 1 Then
                    Ausgabe = ProduceSeaUnit(Prüffonds)
                    If Ausgabe = 0 Then
                        BauModus = 1
                        GoTo Start
                    End If
                ElseIf LuftwaffenBau And OwnAirports > 0 And BauModus <= 1 And Zufallszahl(1, 100) > 90 Then
                    Ausgabe = ProduceAirUnit(AirUnits, Prüffonds)
                    If Ausgabe = 0 Then
                        BauModus = 2
                        GoTo Start
                    End If
                Else
                    Ausgabe = ProduceGroundUnit(Prüffonds)
                End If
            Case KIMittel.KOStärke.SeeLuft
                If LuftwaffenBau And OwnAirports > 0 And BauModus <= 0 Or Zufallszahl(1, 100) >= 85 Then
                    Ausgabe = ProduceAirUnit(AirUnits, Prüffonds)
                    If Ausgabe = 0 Then
                        BauModus = 1
                        GoTo Start
                    End If
                ElseIf OwnLanders > 0 And OwnHarbours > 0 And Zufallszahl(1, 100) >= 60 And BauModus <= 1 Then
                    Ausgabe = ProduceSeaUnit(Prüffonds)
                    If Ausgabe = 0 Then
                        BauModus = 2
                        GoTo Start
                    End If
                Else
                    Ausgabe = ProduceGroundUnit(Prüffonds)
                End If
            Case KIMittel.KOStärke.Infantrie
                If Zufallszahl(1, 100) >= 80 Then
                    Ausgabe = InfisBauen(Prüffonds)
                    If Ausgabe = 0 Then
                        GoTo Alles
                    End If
                Else
                    If HeliDeffensive > 100 Or HeliOffensive > 100 Then
                        If LuftwaffenBau And OwnAirports > 0 Or Zufallszahl(0, 100) >= 70 And OwnAirports > 0 Then
                            Ausgabe = ProduceCopter(Prüffonds)
                        Else
                            GoTo Alles
                        End If
                    Else
                        GoTo Alles
                    End If
                End If
            Case Else
Alles:
                If BauModus <= 2 Then
                    If LuftwaffenBau And OwnAirports > 0 And BauModus <= 0 Then
                        Ausgabe = ProduceAirUnit(AirUnits, Prüffonds)
                        If Ausgabe = 0 Then
                            BauModus = 1
                            GoTo Start
                        End If
                    ElseIf OwnLanders = 0 And BauModus <= 1 Then
                        Ausgabe = ProduceGroundUnit(Prüffonds)
                        If Ausgabe = 0 Then
                            BauModus = 2
                            GoTo Start
                        End If
                    ElseIf OwnLanders > 0 And OwnHarbours > 0 And BauModus <= 2 Then
                        Ausgabe = ProduceSeaUnit(Prüffonds)
                        If Ausgabe = 0 Then
                            BauModus = 3
                            GoTo Start
                        End If
                    Else
                        Ausgabe = ProduceGroundUnit(Prüffonds)
                    End If
                End If
        End Select
        Return Ausgabe
    End Function
    ''' <summary>
    ''' Stellt eine Lufteinheit mit Bodenwaffen her!
    ''' </summary>
    ''' <param name="Prüffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ProduceAirUnit(ByVal EnemyAirForce As Integer, ByVal Prüffonds As Integer) As Integer
        Dim Ausgabe As Integer = 0
        If Prüffonds < 0 Then
            Prüffonds = Spieler.Fonds
        End If
        For I = 0 To Gebäude.Length - 1
            If IsFeldLeer(Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y) Then 'Wir wollen ja was bauen!
                Dim BListe As String() = Gebäude(I).GetBauliste(Gebäude(I).Spieler)
                Dim TeuersterHeli As ObjektEinheit = Nothing
                For I2 = 0 To BListe.Length - 1
                    Dim AirUnit As ObjektEinheit = ObjektLadeklasse.NewEinheit(BListe(I2), Spieler.Spieler, Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y)
                    If AirUnit.CanAttack Then
                        If Gebäude(I).CanBuildUnit(AirUnit, Prüffonds) Then
                            If AirUnit.Bewegungsart = MovementSorts.Helikopter.ToString Or AirUnit.Bewegungsart = MovementSorts.Flugzeug.ToString Then
                                If CanMoveAfterBuilding(AirUnit, AirUnit.X, AirUnit.Y) Then
                                    If AirUnit.CanAttackGroundUnits Or EnemyAirForce > 0 Then
                                        If Gebäude(I).CanBuildUnit(AirUnit, Prüffonds) Then
                                            If TeuersterHeli Is Nothing Then
                                                TeuersterHeli = AirUnit
                                            ElseIf TeuersterHeli.Kosten < AirUnit.Kosten Then
                                                TeuersterHeli = AirUnit
                                            ElseIf TeuersterHeli.Kosten = AirUnit.Kosten And Zufallszahl(0, 2) = 0 Then
                                                TeuersterHeli = AirUnit
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                Next
                If Not TeuersterHeli Is Nothing Then
                    Ausgabe = TeuersterHeli.Kosten * Spieler.Teurungsrate(TeuersterHeli, TeuersterHeli.X, TeuersterHeli.Y)
                    GebäudeAuswählen(KIModiExtern.EinheitBauen, Gebäude(I), TeuersterHeli)
                    Return Ausgabe
                End If
            End If
        Next
        Return Ausgabe
    End Function
    ''' <summary>
    ''' Stellt eine Bodeneinheit mit Bodenwaffen her!
    ''' </summary>
    ''' <param name="Prüffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ProduceGroundUnit(ByVal Prüffonds As Integer) As Integer
        Dim Ausgabe As Integer = 0
        If Prüffonds < 0 Then
            Prüffonds = Spieler.Fonds
        End If
        For I = 0 To Gebäude.Length - 1
            If IsFeldLeer(Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y) Then 'Wir wollen ja was bauen!
                Dim BListe As String() = Gebäude(I).GetBauliste(Gebäude(I).Spieler)
                Dim TeuersterHeli As ObjektEinheit = Nothing
                For I2 = 0 To BListe.Length - 1
                    Dim AirUnit As ObjektEinheit = ObjektLadeklasse.NewEinheit(BListe(I2), Spieler.Spieler, Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y)
                    If Gebäude(I).CanBuildUnit(AirUnit, Prüffonds) Then
                        If AirUnit.IsGroundUnit Then
                            If AirUnit.CanAttack Then
                                If AirUnit.CanAttackGroundUnits Then
                                    If CanMoveAfterBuilding(AirUnit, AirUnit.X, AirUnit.Y) Then
                                        If Gebäude(I).CanBuildUnit(AirUnit, Prüffonds) Then
                                            If Prüffonds > MinimaleFonds Then
                                                If AirUnit.Kosten <= MaximalePreisBoden Or Zufallszahl(1, 100) > 85 Then
                                                    If TeuersterHeli Is Nothing Then
                                                        TeuersterHeli = AirUnit
                                                    ElseIf TeuersterHeli.Kosten < AirUnit.Kosten Then
                                                        TeuersterHeli = AirUnit
                                                    ElseIf TeuersterHeli.Kosten = AirUnit.Kosten And Zufallszahl(0, 2) = 0 Then
                                                        TeuersterHeli = AirUnit
                                                    End If
                                                End If
                                            Else
                                                If TeuersterHeli Is Nothing Then
                                                    TeuersterHeli = AirUnit
                                                ElseIf AirUnit.Kosten >= MinimalerPanzerPreis And Zufallszahl(1, 100) <= 45 Or TeuersterHeli.Kosten < MinimalerPanzerPreis Then
                                                    If AirUnit.Kosten <= MaximalePreisBoden Or Zufallszahl(1, 100) > 85 Then
                                                        TeuersterHeli = AirUnit
                                                    End If
                                                End If
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                Next
                If Not TeuersterHeli Is Nothing Then
                    Ausgabe = TeuersterHeli.Kosten * Spieler.Teurungsrate(TeuersterHeli, TeuersterHeli.X, TeuersterHeli.Y)
                    GebäudeAuswählen(KIModiExtern.EinheitBauen, Gebäude(I), TeuersterHeli)
                    Return Ausgabe
                End If
            End If
        Next
        Return Ausgabe
    End Function
    ''' <summary>
    ''' Stellt eine Seeeinheit mit Bodenwaffen her!
    ''' </summary>
    ''' <param name="Prüffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ProduceSeaUnit(ByVal Prüffonds As Integer) As Integer
        Dim Ausgabe As Integer = 0
        If Prüffonds < 0 Then
            Prüffonds = Spieler.Fonds
        End If
        For I = 0 To Gebäude.Length - 1
            If IsFeldLeer(Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y) Then 'Wir wollen ja was bauen!
                Dim BListe As String() = Gebäude(I).GetBauliste(Gebäude(I).Spieler)
                Dim TeuersterHeli As ObjektEinheit = Nothing
                For I2 = 0 To BListe.Length - 1
                    Dim AirUnit As ObjektEinheit = ObjektLadeklasse.NewEinheit(BListe(I2), Spieler.Spieler, Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y)
                    If Gebäude(I).CanBuildUnit(AirUnit, Prüffonds) Then
                        If AirUnit.IsSeaUnit Then
                            If AirUnit.CanAttack Then
                                If AirUnit.CanAttackGroundUnits Or AirUnit.CanAttackSeaUnits Then
                                    If Gebäude(I).CanBuildUnit(AirUnit, Prüffonds) Then
                                        If CanMoveAfterBuilding(AirUnit, AirUnit.X, AirUnit.Y) Then
                                            If TeuersterHeli Is Nothing Then
                                                TeuersterHeli = AirUnit
                                            ElseIf TeuersterHeli.Kosten < AirUnit.Kosten Then
                                                TeuersterHeli = AirUnit
                                            ElseIf TeuersterHeli.Kosten = AirUnit.Kosten And Zufallszahl(0, 2) = 0 Then
                                                TeuersterHeli = AirUnit
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                Next
                If Not TeuersterHeli Is Nothing Then
                    Ausgabe = TeuersterHeli.Kosten * Spieler.Teurungsrate(TeuersterHeli, TeuersterHeli.X, TeuersterHeli.Y)
                    GebäudeAuswählen(KIModiExtern.EinheitBauen, Gebäude(I), TeuersterHeli)
                    Exit For
                End If
            End If
        Next
        Return Ausgabe
    End Function
    ''' <summary>
    ''' Baut eine Nahkampfeinheit
    ''' </summary>
    ''' <param name="Prüffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ProduceDirectUnit(ByVal Luftwaffenbau As Boolean, ByVal Prüffonds As Integer) As Integer
        Dim Ausgabe As Integer = 0
        If Prüffonds < 0 Then
            Prüffonds = Spieler.Fonds
        End If
        For I = 0 To Gebäude.Length - 1
            If IsFeldLeer(Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y) Then 'Wir wollen ja was bauen!
                Dim BListe As String() = Gebäude(I).GetBauliste(Gebäude(I).Spieler)
                Dim TeuersterHeli As ObjektEinheit = Nothing
                For I2 = 0 To BListe.Length - 1
                    Dim AirUnit As ObjektEinheit = ObjektLadeklasse.NewEinheit(BListe(I2), Spieler.Spieler, Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y)
                    If Gebäude(I).CanBuildUnit(AirUnit, Prüffonds) Then
                        If AirUnit.Reichweitemax = 1 Then
                            If Not AirUnit.IsFlyingUnit Or AirUnit.IsFlyingUnit And Luftwaffenbau Then
                                If AirUnit.CanAttackGroundUnits Then
                                    If CanMoveAfterBuilding(AirUnit, AirUnit.X, AirUnit.Y) Then
                                        If Gebäude(I).CanBuildUnit(AirUnit, Prüffonds) Then
                                            If Prüffonds > MinimaleFonds Then
                                                If TeuersterHeli Is Nothing Then
                                                    TeuersterHeli = AirUnit
                                                ElseIf TeuersterHeli.Kosten < AirUnit.Kosten Then
                                                    TeuersterHeli = AirUnit
                                                ElseIf TeuersterHeli.Kosten = AirUnit.Kosten And Zufallszahl(0, 2) = 0 Then
                                                    TeuersterHeli = AirUnit
                                                End If
                                            Else
                                                If TeuersterHeli Is Nothing Then
                                                    TeuersterHeli = AirUnit
                                                ElseIf AirUnit.Kosten >= MinimalerPanzerPreis And Zufallszahl(1, 100) <= 45 Or TeuersterHeli.Kosten < MinimalerPanzerPreis Then
                                                    TeuersterHeli = AirUnit
                                                End If
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                Next
                If Not TeuersterHeli Is Nothing Then
                    Ausgabe = TeuersterHeli.Kosten * Spieler.Teurungsrate(TeuersterHeli, TeuersterHeli.X, TeuersterHeli.Y)
                    GebäudeAuswählen(KIModiExtern.EinheitBauen, Gebäude(I), TeuersterHeli)
                    Return Ausgabe
                End If
            End If
        Next
        Return Ausgabe
    End Function
    ''' <summary>
    ''' Baut eine Fernkampfeinheit
    ''' </summary>
    ''' <param name="Prüffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ProduceInDirectUnit(ByVal Luftwaffenbau As Boolean, ByVal Prüffonds As Integer) As Integer
        Dim Ausgabe As Integer = 0
        If Prüffonds < 0 Then
            Prüffonds = Spieler.Fonds
        End If
        For I = 0 To Gebäude.Length - 1
            If IsFeldLeer(Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y) Then 'Wir wollen ja was bauen!
                Dim BListe As String() = Gebäude(I).GetBauliste(Gebäude(I).Spieler)
                Dim TeuersterHeli As ObjektEinheit = Nothing
                For I2 = 0 To BListe.Length - 1
                    Dim AirUnit As ObjektEinheit = ObjektLadeklasse.NewEinheit(BListe(I2), Spieler.Spieler, Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y)
                    If Gebäude(I).CanBuildUnit(AirUnit, Prüffonds) Then
                        If AirUnit.Reichweitemax > 1 Then
                            If Not AirUnit.IsFlyingUnit Or AirUnit.IsFlyingUnit And Luftwaffenbau Then

                                If AirUnit.CanAttackGroundUnits Then
                                    If CanMoveAfterBuilding(AirUnit, AirUnit.X, AirUnit.Y) Then
                                        If Gebäude(I).CanBuildUnit(AirUnit, Prüffonds) Then
                                            If Prüffonds > MinimaleFonds Then
                                                If TeuersterHeli Is Nothing Then
                                                    TeuersterHeli = AirUnit
                                                ElseIf TeuersterHeli.Kosten < AirUnit.Kosten Then
                                                    TeuersterHeli = AirUnit
                                                ElseIf TeuersterHeli.Kosten = AirUnit.Kosten And Zufallszahl(0, 2) = 0 Then
                                                    TeuersterHeli = AirUnit
                                                End If
                                            Else
                                                If TeuersterHeli Is Nothing Then
                                                    TeuersterHeli = AirUnit
                                                ElseIf AirUnit.Kosten >= MinimalerPanzerPreis And Zufallszahl(1, 100) <= 45 Or TeuersterHeli.Kosten < MinimalerPanzerPreis Then
                                                    TeuersterHeli = AirUnit
                                                End If
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                Next
                If Not TeuersterHeli Is Nothing Then
                    Ausgabe = TeuersterHeli.Kosten * Spieler.Teurungsrate(TeuersterHeli, TeuersterHeli.X, TeuersterHeli.Y)
                    GebäudeAuswählen(KIModiExtern.EinheitBauen, Gebäude(I), TeuersterHeli)
                    Return Ausgabe
                End If
            End If
        Next
        Return Ausgabe
    End Function
#End Region
#Region "Count Units and Buildings and Stuff like that!"
    ''' <summary>
    ''' Zählt die Lufteinheiten, welche Angreifen können.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountEnemyAirUnits() As Integer
        Dim AirTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X, Y, I)
                    If Not E Is Nothing Then
                        If E.IsFlyingUnit Then
                            If E.CanAttack Then
                                If E.GetSpieler.Team <> Spieler.Team Then
                                    AirTroops += 1
                                End If
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return AirTroops
    End Function
    ''' <summary>
    ''' Zählt die Fernwaffen der Gegner.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountIndirectEnemys() As Integer
        Dim IndirectTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X, Y, I)
                    If Not E Is Nothing Then
                        If E.IsFlyingUnit Then
                            If E.MaximaleReichweite > 1 Then
                                If E.GetSpieler.Team <> Spieler.Team Then
                                    IndirectTroops += 1
                                End If
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return IndirectTroops
    End Function
    ''' <summary>
    ''' Zählt die Direktwaffen der Gegner.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountDirectEnemys() As Integer
        Dim IndirectTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X, Y, I)
                    If Not E Is Nothing Then
                        If E.IsFlyingUnit Then
                            If E.MinimaleReichweite = 1 Or E.Waffe1 <> "Keine" Then
                                If E.GetSpieler.Team <> Spieler.Team Then
                                    IndirectTroops += 1
                                End If
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return IndirectTroops
    End Function
    ''' <summary>
    ''' Wie viele Neutrale Besetzungen es noch gibt!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountNeutralBuildings() As Integer
        Dim IndirectTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim G As ObjektGebäude = Objektverwalter.Spielfeld.Landschaften(X, Y, I).Gebäude
                    If Not G Is Nothing Then
                        If G.Spieler = 0 Then
                            If G.Besetzung > 0 Then
                                IndirectTroops += 1
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return IndirectTroops
    End Function
    ''' <summary>
    ''' Wie viele feindliche Besetzungen es noch gibt!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountEnemyBuildings() As Integer
        Dim IndirectTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim G As ObjektGebäude = Objektverwalter.Spielfeld.Landschaften(X, Y, I).Gebäude
                    If Not G Is Nothing Then
                        If G.GetSpieler.Team <> Spieler.Team Then
                            If G.Besetzung > 0 Then
                                IndirectTroops += 1
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return IndirectTroops
    End Function
    ''' <summary>
    ''' Zählt die Zahl der Einheiten die Bomber angreifen können!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountAntiAirUnits() As Integer
        Dim AirTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X, Y, I)
                    If Not E Is Nothing Then
                        If E.Spieler = Spieler.Spieler Then
                            If E.IsAttackable(New EinheitBomber(0, X, Y, False), False, False) Then
                                AirTroops += 1
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return AirTroops
    End Function
    ''' <summary>
    ''' Zählt die Zahl der feindlichen Einheiten die Bomber angreifen können!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountEnemyAntiAirUnits() As Integer
        Dim AirTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X, Y, I)
                    If Not E Is Nothing Then
                        If E.GetSpieler.Team <> Spieler.Team Then
                            If E.IsAttackable(New EinheitBomber(0, X, Y, False), False, False) Then
                                AirTroops += 1
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return AirTroops
    End Function
    ''' <summary>
    ''' Zählt die Zahl der Bodeneinheiten + Amphibientruppen
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountGroundUnits() As Integer
        Dim AirTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X, Y, I)
                    If Not E Is Nothing Then
                        If E.Spieler = Spieler.Spieler Then
                            If E.IsGroundUnit Then
                                AirTroops += 1
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return AirTroops
    End Function
    ''' <summary>
    ''' Zählt die Zahl der feindlichen Bodeneinheiten + Amphibientruppen
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountEnemyGroundUnits() As Integer
        Dim AirTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X, Y, I)
                    If Not E Is Nothing Then
                        If E.GetSpieler.Team = Spieler.Team Then
                            If E.IsGroundUnit Then
                                AirTroops += 1
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return AirTroops
    End Function
    ''' <summary>
    ''' Zählt die Zahl der feindlichen Seeeinheiten
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountEnemySeaUnits() As Integer
        Dim AirTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X, Y, I)
                    If Not E Is Nothing Then
                        If E.GetSpieler.Team = Spieler.Team Then
                            If E.IsSeaUnit Then
                                If E.CanAttack Then
                                    AirTroops += 1
                                End If
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return AirTroops
    End Function
    ''' <summary>
    ''' Zählt die Zahl der feindlichen Einheiten
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountEnemyUnits() As Integer
        Dim AirTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X, Y, I)
                    If Not E Is Nothing Then
                        If E.GetSpieler.Team = Spieler.Team Then
                            AirTroops += 1
                        End If
                    End If
                Next
            Next
        Next
        Return AirTroops
    End Function
    ''' <summary>
    ''' Zählt die Zahl der feindlichen Helikopter
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountEnemyCopters() As Integer
        Dim AirTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X, Y, I)
                    If Not E Is Nothing Then
                        If E.GetSpieler.Team = Spieler.Team Then
                            If E.Bewegungsart = MovementSorts.Helikopter.ToString Then
                                If Not E.HasNoWeapons Then
                                    AirTroops += 1
                                End If
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return AirTroops
    End Function
    ''' <summary>
    ''' Zählt die eigenen Truppen
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountOwnUnits() As Integer
        Dim AirTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X, Y, I)
                    If Not E Is Nothing Then
                        If E.Spieler = Spieler.Spieler Then
                            AirTroops += 1
                        End If
                    End If
                Next
            Next
        Next
        Return AirTroops
    End Function
    ''' <summary>
    ''' Wie viele Basen haben wir.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountOwnBases() As Integer
        Dim IndirectTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim G As ObjektGebäude = Objektverwalter.Spielfeld.Landschaften(X, Y, I).Gebäude
                    If Not G Is Nothing Then
                        If G.GetSpieler.Team <> Spieler.Team Then
                            If TypeOf G Is GebäudeBasis Then
                                IndirectTroops += 1
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return IndirectTroops
    End Function
    ''' <summary>
    ''' Wie viele Flughafen haben wir.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountOwnAirports() As Integer
        Dim IndirectTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim G As ObjektGebäude = Objektverwalter.Spielfeld.Landschaften(X, Y, I).Gebäude
                    If Not G Is Nothing Then
                        If G.GetSpieler.Team <> Spieler.Team Then
                            If TypeOf G Is GebäudeFlughafen Then
                                IndirectTroops += 1
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return IndirectTroops
    End Function
    ''' <summary>
    ''' Wie viele Hafen haben wir.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CountOwnPorts() As Integer
        Dim IndirectTroops As Integer = 0
        Dim Schlacht As Integer = 0
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht Then Schlacht += 1
        For I = 0 To Schlacht
            For X = 0 To Objektverwalter.Spielfeld.Breite - 1
                For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                    Dim G As ObjektGebäude = Objektverwalter.Spielfeld.Landschaften(X, Y, I).Gebäude
                    If Not G Is Nothing Then
                        If G.GetSpieler.Team <> Spieler.Team Then
                            If TypeOf G Is GebäudeHafen Then
                                IndirectTroops += 1
                            End If
                        End If
                    End If
                Next
            Next
        Next
        Return IndirectTroops
    End Function
#End Region
#Region "Checking Stuff functions giving back true or false or integers. This functions simply rock!"
    ''' <summary>
    ''' Sollen wir Infis bauen?
    ''' </summary>
    ''' <param name="Infis"></param>
    ''' <param name="NeutraleGebäude"></param>
    ''' <param name="EnemyBuildings"></param>
    ''' <param name="Basen">Die Anzahl der eigenen Basen!</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function InfiBau(ByVal Infis As Integer, ByVal NeutraleGebäude As Integer, ByVal EnemyBuildings As Integer, ByVal Basen As Integer, ByVal AntiAirUnits As Integer, ByVal EnemyAirUnits As Integer) As Boolean
        Dim Income As Integer = Spieler.Einkommen
        If FreeBase(Basen) Then 'Wir brauchen Basen um das zu tun.
            If Infis < 5 Then '5 halte ich für angemessen
                If NeutraleGebäude > 3 Or EnemyBuildings / Spieler.CountEnemies > Spieler.Geldgebäude Then 'Auch hier nur Testvariablen
                    Return True
                End If
            ElseIf Income <= MinimalEinkommen Then
                Return True
            ElseIf Objektverwalter.Spielfeld.GetSpielgröße < MinimaleKartenGröße Then
                If Income < MinimalEinkommen * 2 Then
                    If Not AntiAirBau(AntiAirUnits, EnemyAirUnits) Then
                        Return True
                    End If
                End If
            End If
        End If
        Return False
    End Function 'Testwerte
    ''' <summary>
    ''' Gibt es eine freie Basis?
    ''' </summary>
    ''' <param name="Basen"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function FreeBase(ByVal Basen As Integer) As Boolean
        If Basen > 0 Then
            For I = 0 To Gebäude.Length - 1
                If TypeOf Gebäude(I) Is GebäudeBasis Then
                    If Objektverwalter.Spielfeld.Einheiten(Gebäude(I).Rechteck.X, Gebäude(I).Rechteck.Y, Schlachtfeld) Is Nothing Then
                        Return True
                    End If
                End If
            Next
        End If
        Return False
    End Function
    ''' <summary>
    ''' Brauchen wir was gegen Luftwaffe (T-Heli's und T-Flugzeuge zählen nicht!) 
    ''' </summary>
    ''' <param name="AntiAirUnits"></param>
    ''' <param name="EnemyAirUnits"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function AntiAirBau(ByVal AntiAirUnits As Integer, ByVal EnemyAirUnits As Integer) As Boolean
        If EnemyAirUnits > 0 Then 'Sonst brauchen wir das ja wohl kaum!!!
            If AntiAirUnits <= 0 Then
                Return True
            ElseIf EnemyAirUnits / 2 > AntiAirUnits / 1 Then 'Diw Teiler sind noch Variabel
                Return True
            End If
        End If
        Return False
    End Function 'Testwerte
    ''' <summary>
    ''' Berechnet was die teuerste Einheit dieses Gebäudes ist.
    ''' </summary>
    ''' <param name="BauGebäude"></param>
    ''' <param name="Fonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function GetTeuersteEinheitenPreis(ByVal BauGebäude As ObjektGebäude, ByVal Fonds As Integer) As Integer
        Dim Preis As Integer = -1
        For Each Einheit In BauGebäude.GetBauliste(BauGebäude.Spieler)
            If BauGebäude.CanBuildUnit(Einheit, Fonds) Then
                Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(Einheit, Spieler.Spieler, BauGebäude.Rechteck.X, BauGebäude.Rechteck.Y, )
                Dim NeuerPreis As Integer = E.Kosten * Spieler.Teurungsrate(E, BauGebäude.Rechteck.X, BauGebäude.Rechteck.Y)
                If NeuerPreis > Preis Then
                    Preis = NeuerPreis
                ElseIf NeuerPreis = Preis And Zufallszahl(0, 1) = 0 Then
                    Preis = NeuerPreis
                End If
            End If
        Next
        Return Preis
    End Function
    ''' <summary>
    ''' Wie teuer wäre den eine Superwaffe?
    ''' </summary>
    ''' <param name="FondsNächsteRunde"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function GetExpensivestUnitCosts(ByVal FondsNächsteRunde As Integer) As Integer
        Dim TeuersteEinheitNächsteRunde As Integer = -1
        For Each G In Gebäude
            If G.GetBauliste(G.Spieler).Length > 0 Then
                Dim T As Integer = GetTeuersteEinheitenPreis(G, FondsNächsteRunde)
                If T > TeuersteEinheitNächsteRunde Then TeuersteEinheitNächsteRunde = T
            End If
        Next
        Return TeuersteEinheitNächsteRunde
    End Function
    ''' <summary>
    ''' Gibt den Abstand zur nähesten feindlichen Luftwaffe zurück! UV
    ''' </summary>
    ''' <param name="G"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function GetAirDistance(ByVal G As ObjektGebäude) As Integer
        Dim WSS As New Wegsuchsystem(New EinheitJäger(Spieler.Spieler, G.Rechteck.X, G.Rechteck.Y, False), , False)
        Return WSS.WegsuchenBisGegenAngriff
    End Function
    ''' <summary>
    ''' Können wir eine Anti-Air Einheit bauen?
    ''' </summary>
    ''' <param name="G"></param>
    ''' <param name="Prüffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CanProduceAntiAir(ByVal G As ObjektGebäude, ByVal Prüffonds As Integer) As Boolean
        Dim BListe As String() = G.GetBauliste(G.Spieler)
        For I = 0 To BListe.Length - 1
            Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(BListe(I), Spieler.Spieler, G.Rechteck.X, G.Rechteck.Y)
            If G.CanBuildUnit(E, Prüffonds) Then
                If E.CanAttackAirUnits Then
                    Return True
                End If
            End If
        Next
        Return False
    End Function
    ''' <summary>
    ''' Können wir eine Helis bauen?
    ''' </summary>
    ''' <param name="G"></param>
    ''' <param name="Prüffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CanProduceAttackCopters(ByVal G As ObjektGebäude, ByVal Prüffonds As Integer) As Boolean
        Dim BListe As String() = G.GetBauliste(G.Spieler)
        For I = 0 To BListe.Length - 1
            Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(BListe(I), Spieler.Spieler, G.Rechteck.X, G.Rechteck.Y)
            If G.CanBuildUnit(E, Prüffonds) Then
                If E.Bewegungsart = MovementSorts.Helikopter.ToString Then
                    If E.CanAttack Then
                        Return True
                    End If
                End If
            End If
        Next
        Return False
    End Function
    ''' <summary>
    ''' Sollten wir TTP's oder T-Helis bauen?
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function InfiTransportBau(ByVal Flughäfen As Integer, ByVal TFlugzeuge As Integer, ByVal Infis As Integer, ByVal NeutralBuildings As Integer, ByVal EnemyBuildings As Integer, ByVal OwnBases As Integer, ByVal TTPS As Integer, ByVal THelis As Integer, ByVal AntiAirUnits As Integer, ByVal EnemyAirUnits As Integer) As Boolean
        If LuftTransportBau(Flughäfen, TFlugzeuge) Then
            Return True
        ElseIf Objektverwalter.Spielfeld.GetSpielgröße > KartenGrößeFürInfiTransport Then
            If Infis > 2 Or InfiBau(Infis, NeutralBuildings, EnemyBuildings, OwnBases, AntiAirUnits, EnemyAirUnits) Then
                If TTPS < 2 Or THelis < 2 Then
                    Return True
                End If
            End If
        End If
        Return False
    End Function
    ''' <summary>
    ''' Gibt zurück ob wir T-Flugzeuge brauchen!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function LuftTransportBau(ByVal Flughäfen As Integer, ByVal TFLugzeue As Integer) As Boolean
        If Flughäfen > 0 Then
            If TFLugzeue < 3 Then
                If Spieler.Bauliste.GetWert("T-Flugzeug") > 0 Then
                    For Each G In Gebäude
                        If TypeOf G Is GebäudeBasis Then
                            Dim E As ObjektEinheit = New EinheitJagdpanzer(Spieler.Spieler, G.Rechteck.X, G.Rechteck.Y, False)
                            Dim WSS As New Wegsuchsystem(E, E.X, E.Y, Objektverwalter.Spielfeld.MomentaneSchlacht, -1)
                            Dim Ziel As Point = GetNähestenNahkampfFeind(E, WSS)
                            If Ziel.X < 0 And Ziel.Y < 0 Then
                                Return True
                            End If
                        End If
                    Next
                End If
            End If
        End If
        Return False
    End Function
    ''' <summary>
    ''' Was die besten Truppen dieses KO's sind.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function GetKOStärke() As KOStärke
        Dim InfantrieOffensive As Integer = Spieler.KOS(0).GetOffensivStärke(New EinheitInfanterie(Spieler.Spieler, 0, 0))
        Dim PanzerOffensive As Integer = Spieler.KOS(0).GetOffensivStärke(New EinheitJagdpanzer(Spieler.Spieler, 0, 0))
        Dim LuftOffensive As Integer = Spieler.KOS(0).GetOffensivStärke(New EinheitJäger(Spieler.Spieler, 0, 0))
        Dim FernOffensive As Integer = Spieler.KOS(0).GetOffensivStärke(New EinheitArtillerie(Spieler.Spieler, 0, 0))
        Dim SeeOffensive As Integer = Spieler.KOS(0).GetOffensivStärke(New EinheitKreuzer(Spieler.Spieler, 0, 0))
        Dim InfantrieDeffensive As Integer = Spieler.KOS(0).GetDeffensivStärke(New EinheitInfanterie(Spieler.Spieler, 0, 0))
        Dim PanzerDeffensive As Integer = Spieler.KOS(0).GetDeffensivStärke(New EinheitJagdpanzer(Spieler.Spieler, 0, 0))
        Dim LuftDeffensive As Integer = Spieler.KOS(0).GetDeffensivStärke(New EinheitJäger(Spieler.Spieler, 0, 0))
        Dim FernDeffensive As Integer = Spieler.KOS(0).GetDeffensivStärke(New EinheitArtillerie(Spieler.Spieler, 0, 0))
        Dim SeeDeffensive As Integer = Spieler.KOS(0).GetDeffensivStärke(New EinheitKreuzer(Spieler.Spieler, 0, 0))
        If InfantrieOffensive > 100 Or InfantrieDeffensive > 100 Then
            If PanzerOffensive > 100 Then
                Return KOStärke.Alle
            Else
                Return KOStärke.Infantrie
            End If
        ElseIf PanzerOffensive > 100 Or PanzerDeffensive > 100 Then
            If LuftOffensive > 100 Or LuftDeffensive > 100 Then
                Return KOStärke.Direkt
            Else
                Return KOStärke.Boden
            End If
        ElseIf FernDeffensive > 100 Or FernOffensive > 100 Or Spieler.KOS(0).Reichweite > 0 Then
            Return KOStärke.Indirekt
        ElseIf LuftOffensive > 100 Or LuftDeffensive > 100 Then
            If SeeDeffensive > 100 Or SeeOffensive > 100 Then
                Return KOStärke.SeeLuft
            Else
                Return KOStärke.Luft
            End If
        ElseIf SeeDeffensive > 100 Or SeeOffensive > 100 Then
            Return KOStärke.See
        ElseIf Spieler.KOS(0).NahkampfReichweitenBonus > 0 Then
            Return KOStärke.Direkt
        Else
            Return KOStärke.Alle
        End If
    End Function
#End Region
#End Region
    ''' <summary>
    ''' Mit dieser Funktion beenden die einfachen KI's die Runde
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub RundenEnde()
        If Spieler.KOS(0).Gabemodus = ObjektKO.Gabemodi.Keine Then
            Dim GabefüllstandKO1 As Integer = Spieler.KOS(0).Gabeleiste
            Dim GabefüllstandKO2 As Integer = -1
            If IsNothing(Spieler.KOS(1)) = False Then
                GabefüllstandKO2 = Spieler.KOS(1).Gabeleiste
            End If
            If GabefüllstandKO2 >= 0 Then
                GabefüllstandKO1 = ((Spieler.KOS(0).SpezialgabeKosten + Spieler.KOS(0).Gabekosten) * Spieler.KOS(0).Sternkosten - GabefüllstandKO1)
                GabefüllstandKO2 = ((Spieler.KOS(1).SpezialgabeKosten + Spieler.KOS(1).Gabekosten) * Spieler.KOS(1).Sternkosten - GabefüllstandKO2)
                If GabefüllstandKO1 < 1500 And GabefüllstandKO2 < 1500 Then
                    If Spieler.KOS(1).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenEnde And Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.Beides Then
                        RundenEndeMitWechsel = True
                        Spieler.Wechsel()
                    ElseIf Spieler.KOS(1).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenEnde And Spieler.KOS(0).GabeEinsatzstelle = ObjektKO.KIGabeEinsatzstellen.RundenAnfang Then
                        RundenEndeMitWechsel = True
                        Spieler.Wechsel()
                    End If
                ElseIf GabefüllstandKO1 - GabefüllstandKO2 < -1000 Then
                    RundenEndeMitWechsel = True
                    Spieler.Wechsel()
                End If
            End If
        ElseIf Spieler.KOS(0).Gabemodus = ObjektKO.Gabemodi.Doppelgabe Then
            If Spieler.KOS(1).Gabemodus = ObjektKO.Gabemodi.Keine Then
                RundenEndeMitWechsel = True
                Spieler.Wechsel()
            End If
        End If
        Schleife = True
    End Sub
#Region "Ration"
    Private Function GetNähestesRationsFeld(ByVal Einheit As ObjektEinheit, ByRef WSS As Wegsuchsystem) As Point
        Dim Ziel As Point = New Point(-1, -1)
        Dim MinBew As Integer = -1
        For X = 0 To Objektverwalter.Spielfeld.Breite - 1
            For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                Dim BewPunkte As Integer = WSS.getBewegungspunktekosten(X, Y)
                If BewPunkte >= 0 Then
                    If Not IsBeschussFeldVon(X, Y, BeschussArten.HeilungEigene) Then
                        If Einheit.getKP < MinimaleKP Then
                            'Jetzt wird es schwerer.
                            Dim G As ObjektGebäude = Objektverwalter.Spielfeld.Landschaften(X, Y, Schlachtfeld).Gebäude
                            If Not G Is Nothing Then
                                If G.Spieler = Spieler.Spieler Then
                                    If IsFeldLeer(X, Y, Einheit) Then
                                        Dim BList() As String = G.GetBauliste(G.Spieler)
                                        If BList.Length > 0 Then
                                            If BList.Contains(Einheit.EinheitenID) Then
                                                If BewPunkte < MinBew Or MinBew < 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                End If
                                            End If
                                        ElseIf G.Versorung Then
                                            If ObjektLadeklasse.GetBauliste("BASIS").Contains(Einheit.EinheitenID) Then
                                                If BewPunkte < MinBew Or MinBew < 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                End If
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        ElseIf RationsEinheitNebenAn(X, Y, Einheit) Then
                            If IsFeldLeer(X, Y, Einheit) Then
                                If BewPunkte < MinBew Or MinBew < 0 Then
                                    MinBew = BewPunkte
                                    Ziel = New Point(X, Y)
                                ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                                    MinBew = BewPunkte
                                    Ziel = New Point(X, Y)
                                End If
                            End If
                        Else
                            Dim G As ObjektGebäude = Objektverwalter.Spielfeld.Landschaften(X, Y, Schlachtfeld).Gebäude
                            If Not G Is Nothing Then
                                If G.Spieler = Spieler.Spieler Then
                                    If IsFeldLeer(X, Y, Einheit) Then
                                        Dim BList() As String = G.GetBauliste(G.Spieler)
                                        If BList.Length > 0 Then
                                            If BList.Contains(Einheit.EinheitenID) Then
                                                If BewPunkte < MinBew Or MinBew < 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                End If
                                            End If
                                        ElseIf G.Versorung Then
                                            If ObjektLadeklasse.GetBauliste("BASIS").Contains(Einheit.EinheitenID) Then
                                                If BewPunkte < MinBew Or MinBew < 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                                                    MinBew = BewPunkte
                                                    Ziel = New Point(X, Y)
                                                End If
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    Else
                        If BewPunkte < MinBew Or MinBew < 0 Then
                            MinBew = BewPunkte
                            Ziel = New Point(X, Y)
                        ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                            MinBew = BewPunkte
                            Ziel = New Point(X, Y)
                        End If
                    End If
                End If
            Next
        Next
        Return Ziel
    End Function
    ''' <summary>
    ''' Gibt zurück ob neben an eine Einheit ist die Ration verteilen kann.
    ''' </summary>
    ''' <param name="X"></param>
    ''' <param name="Y"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Function RationsEinheitNebenAn(ByVal X As Integer, ByVal Y As Integer, ByVal Einheit As ObjektEinheit) As Boolean
        Dim X2 As Integer = X
        Dim Y2 As Integer = Y
        For I = 0 To 3
            Select Case I
                Case 0
                    X2 -= 1
                Case 1
                    X2 += 1
                    Y2 -= 1
                Case 2
                    X2 += 1
                    Y2 += 1
                Case 3
                    X2 -= 1
                    Y2 += 1
            End Select
            If Objektverwalter.Spielfeld.OnMap(X2, Y2) Then
                Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X2, Y2, Schlachtfeld)
                If Not E Is Nothing Then
                    If E.Spieler = Spieler.Spieler Then
                        If E.Fähigkeit = "Ration" Then
                            If Not E.Equals(Einheit) Then
                                Return True
                            End If
                        End If
                    End If
                End If
            End If
        Next
        Return False
    End Function
    Private Function GetNähestesRationsVerteilFeld(ByVal E As ObjektEinheit, ByRef WSS As Wegsuchsystem) As Point
        Dim Ziel As Point = New Point(-1, -1)
        Dim MinBew As Integer = -1
        For X = 0 To Objektverwalter.Spielfeld.Breite - 1
            For Y = 0 To Objektverwalter.Spielfeld.Höhe - 1
                Dim BewPunkte As Integer = WSS.getBewegungspunktekosten(X, Y)
                If BewPunkte >= 0 Then
                    If IsVersorgungsEinheitNebenAn(X, Y) Then
                        If BewPunkte < MinBew Or MinBew < 0 Then
                            MinBew = BewPunkte
                            Ziel = New Point(X, Y)
                        ElseIf BewPunkte = MinBew And Zufallszahl(0, 2) = 0 Then
                            MinBew = BewPunkte
                            Ziel = New Point(X, Y)
                        End If
                    End If
                End If
            Next
        Next
        Return Ziel
    End Function
    Private Function IsVersorgungsEinheitNebenAn(ByVal X As Integer, ByVal Y As Integer) As Boolean
        Dim X2 As Integer = X
        Dim Y2 As Integer = Y
        For I = 0 To 3
            Select Case I
                Case 0
                    X2 -= 1
                Case 1
                    X2 += 1
                    Y2 -= 1
                Case 2
                    X2 += 1
                    Y2 += 1
                Case 3
                    X2 -= 1
                    Y2 += 1
            End Select
            If Objektverwalter.Spielfeld.OnMap(X2, Y2) Then
                Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X2, Y2, Schlachtfeld)
                If Not E Is Nothing Then
                    If E.Spieler = Spieler.Spieler Then
                        If E.IsLowPowerUnit(MinimalerTreibstoff, MinimaleMunition, MinimaleKP) Then
                            If E.getKP >= MinimaleKP Then
                                Return True
                            End If
                        End If
                    End If
                End If
            End If
        Next
        Return False
    End Function
#End Region
End Class
